黑马程序员技术交流社区
标题:
关于多生产者、多消费者 停止程序问题------>求大神指点
[打印本页]
作者:
小歪
时间:
2014-4-20 22:05
标题:
关于多生产者、多消费者 停止程序问题------>求大神指点
关于多生产者、多消费者 停止程序问题
看完毕老师的多生产者和多消费者后,也写出了代码,但是代码中一直在生产、消费状态,现在如果加入条件使其只生产、消费100个商品后顺利结束程序,有什么好方法,毕老师后面讲的让线程强制启动避免程序挂起,我也想试着加入到多生产、多消费程序中,却不知道从何下手,可能是本人技术不到家,最后听一位朋友建议在生产者和消费者中分别加入了静态(static)的计数器(count)才算解决,可毕竟静态(static)对象是无法在内存中清除的,有没有更好的方法,哪位大神教教我。
具体代码如下:
package ClassPackage;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
利用JDK1.5新特性 解决 “多生产者、多消费者问题”
1、实现多个个线程同时生产、多个线程同时消费状态
2、不能出现共享资源安全问题
3、不能出现死锁状态
4、唤醒线程时,只能唤醒对方线程,不可唤醒本方线程
5、生产、消费100个产品后,程序结束
*/
class Resource{ //共享资源类
private String obj; //当前操作资源对象
private int count=1 ; //资源
private boolean flag=false;
public int getCount()
{
return count;
}
//一把锁,两个线程池
private Lock lock=new ReentrantLock();
private Condition con_pro=lock.newCondition();
private Condition con_con=lock.newCondition();
public void set(String user)
{
lock.lock();
try {
while(flag)
{
con_pro.await();
}
this.obj=user;
System.out.println(Thread.currentThread().getName()+":"+obj+"---->生产商品"+count);
flag=true;
con_con.signal(); //唤醒消费者线程池中第一个线程
} catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock(); //无论是否出现异常 最后必须放开锁
}
}
public void get(String obj)
{
lock.lock();
try {
while(!flag)
{
con_con.await();
}
System.out.println(Thread.currentThread().getName()+":"+obj+"--------------->消费商品"+count++);
flag=false;
con_pro.signal();//唤醒生产者线程池中第一个线程
} catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock(); //无论是否出现异常 最后必须放开锁
}
}
}
class Producer implements Runnable
{
static int count=0;
private Resource res;
public Producer(Resource res)
{
this.res=res;
}
public void run() {
while(count<100)
{
count++;
res.set("生产者");
}
}
}
class Consumer implements Runnable
{
static int count=0;
private Resource res;
int num=1;
public Consumer(Resource res)
{
this.res=res;
}
public void run() {
while(count<100)
{
count++;
res.get("消费者");
}
}
}
public class Test30 {
public static void main(String args[])
{
Resource r=new Resource();
Producer pro=new Producer(r);
Consumer con=new Consumer(r);
Thread t1=new Thread(pro);
Thread t2=new Thread(pro);
//两个生产者线程、两个消费者线程
Thread t3=new Thread(con);
Thread t4=new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
复制代码
运行后貌似解决了问题,但脑子里还是有点稀里糊涂:
QQ截图20140420220426.png
(154.42 KB, 下载次数: 2)
下载附件
2014-4-20 22:03 上传
有没有更好的方法,受教了!!!!
作者:
小歪
时间:
2014-4-20 22:08
还有就是 如果将 84行 和 85行 位置换一下,线程就又会挂起,谁帮忙讲解一下?
作者:
小歪
时间:
2014-4-21 08:06
没人知道吗????
作者:
osully
时间:
2014-4-21 10:11
让函数自身返回值 改成boolean 类型应该可以尝试一下
你看看下面我改了下还算符合你的要求不
应该算是解决了静态的不?
package NoUseArea;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
利用JDK1.5新特性 解决 “多生产者、多消费者问题”
1、实现多个个线程同时生产、多个线程同时消费状态
2、不能出现共享资源安全问题
3、不能出现死锁状态
4、唤醒线程时,只能唤醒对方线程,不可唤醒本方线程
5、生产、消费100个产品后,程序结束
*/
class Resource { // 共享资源类
private String obj; // 当前操作资源对象
private int count = 0; // 资源
private boolean flag = false;
public int getCount() {
return count;
}
// 一把锁,两个线程池
private Lock lock = new ReentrantLock();
private Condition con_pro = lock.newCondition();
private Condition con_con = lock.newCondition();
public boolean set(String user) {
lock.lock();
try {
while (flag) {
con_pro.await();
}
this.obj = user;
if (count < 100) {
System.out.println(Thread.currentThread().getName() + ":" + obj
+ "---->生产商品" + ++count);
}
flag = true;
con_con.signal();
if (count < 100)
return true;
return false;
}
catch (Exception e) {
e.printStackTrace();
}
finally {
lock.unlock();
}
return false;
}
//因为到100的时候所有线程都需要被唤醒,而且100只想被运行一次
boolean b = true;
public boolean get(String obj) {
lock.lock();
try {
while (!flag) {
con_con.await();
}
if (count < 100) {
System.out.println(Thread.currentThread().getName() + ":" + obj
+ "--------------->消费商品" + count);
}
if (count == 100) {
synchronized (this) {
if (b) {
System.out.println(Thread.currentThread().getName()
+ ":" + obj + "--------------->消费商品" + count);
b = false;
flag = false;
con_pro.signal();
}
return false;
}
}
flag = false;
con_pro.signal();
return true;
}
catch (Exception e) {
e.printStackTrace();
}
finally {
lock.unlock(); // 无论是否出现异常 最后必须放开锁
}
return false;
}
}
class Producer implements Runnable {
private Resource res;
public Producer(Resource res) {
this.res = res;
}
public void run() {
boolean b = res.set("生产者");
while (b) {
b = res.set("生产者");
}
}
}
class Consumer implements Runnable {
private Resource res;
public Consumer(Resource res) {
this.res = res;
}
public void run() {
boolean b = res.get("消费者");
while (b) {
b = res.get("消费者");
}
}
}
public class Test30 {
public static void main(String args[]) {
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
// 两个生产者线程、两个消费者线程
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2