生产者/消费者模式
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();
\}
\}
交替执行,很完美
- 多生产与多消费:操作值-假死
* 先看例子,找到问题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()。
还没有评论,来说两句吧...