本文共 3720 字,大约阅读时间需要 12 分钟。
1.一生产与一消费:操作值 * 屁话没有,直接看例子 public class P { private String lock; public P(String lock){ super(); this.lock=lock; } public void setValue(){ try{ synchronized (lock){ if(!ValueObject.value.equals("")){ lock.wait(); } String value=System.currentTimeMillis()+"_"+System.nanoTime(); System.out.println("set 的值是"+value); ValueObject.value=value; lock.notify(); } }catch (InterruptedException e){ e.printStackTrace(); } } } public class C { private String lock; public C(String lock){ super(); this.lock=lock; } public void getValue(){ try{ synchronized (lock){ if(ValueObject.value.equals("")){ lock.wait(); } System.out.println("get的值是"+ValueObject.value); ValueObject.value=""; lock.notify(); } }catch (InterruptedException e){ e.printStackTrace(); } } } public class ValueObject { public static String value=""; } public class ThreadP extends Thread{ private P p; public ThreadP(P p){ super(); this.p=p; } @Override public void run() { while (true){ p.setValue(); } } } public class ThreadC extends Thread{ private C r; public ThreadC(C r){ super(); this.r=r; } @Override public void run() { while(true){ r.getValue(); } } } public class Run { public static void main(String[] args){ String lock=new String(""); P p=new P(lock); C r=new C(lock); ThreadP threadP=new ThreadP(p); ThreadC threadC=new ThreadC(r); threadP.start(); threadC.start(); } } 交替执行,很完美 2. 多生产与多消费:操作值-假死 * 先看例子,找到问题 public class C { private String lock; public C(String lock){ super(); this.lock=lock; } public void getValue(){ try{ synchronized (lock){ while (ValueObject.value.equals("")){ System.out.println("消费者 "+Thread.currentThread().getName()+" WAITING了*"); lock.wait(); } System.out.println("消费者 "+Thread.currentThread().getName()+" RUNNABLE了"); ValueObject.value=""; lock.notify(); } }catch (InterruptedException e){ e.printStackTrace(); } } } public class P { private String lock; public P(String lock) { super(); this.lock = lock; } public void setValue() { try { synchronized (lock) { while (!ValueObject.value.equals("")) { System.out.println("生产者" + Thread.currentThread().getName() + " WAITINGl *"); lock.wait(); } System.out.println("生产者 " + Thread.currentThread().getName() + " RUNNABLE了"); String value = System.currentTimeMillis() + "_" + System.nanoTime(); ValueObject.value = value; lock.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } } public class ThreadC extends Thread { private C c; public ThreadC(C r){ super(); this.c=r; } @Override public void run() { while(true){ c.getValue(); } } } public class ThreadP extends Thread{ private P p; public ThreadP(P p){ super(); this.p=p; } @Override public void run() { while(true){ p.setValue(); } } } public class Run { public static void main(String[] args) throws InterruptedException{ String lock=new String(""); P p=new P(lock); C r=new C(lock); ThreadP[] threadP=new ThreadP[2]; ThreadC[] threadC=new ThreadC[2]; for(int i=0;i<2;i++){ threadP[i]=new ThreadP(p); threadP[i].setName("生产者 "+(i+1)); threadC[i]=new ThreadC(r); threadC[i].setName("消费者 "+(i+1)); threadP[i].start(); threadC[i].start(); } Thread.sleep(5000); Thread[] threads=new Thread[Thread.currentThread().getThreadGroup().activeCount()]; Thread.currentThread().getThreadGroup().enumerate(threads); for(int i=0;i<threads.length;i++){ System.out.println(threads[i].getName()+" "+threads[i].getState()); } } } 效果: ..... 消费者 消费者 2 WAITING了* 消费者 消费者 1 WAITING了* main RUNNABLE Monitor Ctrl-Break RUNNABLE 生产者 1 WAITING 消费者 1 WAITING 生产者 2 WAITING 消费者 2 WAITING * 分析:notify()是随机唤醒的,他并不知道谁是生产者谁是消费者,仅仅去唤醒一个wait的线程 考虑这样一种情况:value中有数据,两个生产者都处于等待状态,然后执行了一个消费者线程, 线程中有数据了,唤醒一个线程,该线程为其中一个生产者,该生产者检测没有数据,生产一个数据, 然后唤醒一个线程,因为另外一个线程处于等待状态,所以刚好唤醒了该线程,如此,消费者就不能得到执行了, 就会陷入相互等待。 *解决办法:把notify()改成notifyAll()。转载地址:http://fmjqi.baihongyu.com/