等待/通知模式最经典的案例即生产者/消费者模式。
1.一生产与一消费:操作值
2.多生产与多消费:操作值
多生产与多消费有可能会造成假死,假死即线程进入warning等待状态。若全部线程进入warning状态,则整个项目处于停止状态。假死出现的原因即有可能连续唤醒同类,即生产者唤醒生产者,消费者唤醒消费者。
解决假死的办法即把notify()改为notifyAll(),这样它的原理不光是通知同类线程也包括异类。
下面的几种模式的目的是:生产者想List对象中放入数据,消费者从List中取出数据,List最大容量为1。
3.一生产与一消费:操作栈
4.一生产与一消费
对于wait条件改变解决方案是if换做while,对于假死仍采用notify换做notifyAll
5.多生产与一消费
6.多生产与多消费
MyStack.java
public class MyStack {
private List list=new ArrayList();
synchronized public void push(){
try{
while(list.size()==1){
//System.out.println("push操作中的"+Thread.currentThread().getName()+"线程状态是wait状态的");
this.wait();
}
list.add("anything="+Math.random());
this.notifyAll();
System.out.println("push="+list.size());
}catch(InterruptedException e){
e.printStackTrace();
}
}
synchronized public String pop(){
String returnString="";
try{
while(list.size()==0){
System.out.println("pop操作中的"+Thread.currentThread().getName()+"线程状态是wait状态的");
this.wait();
}
returnString=""+list.get(0);
list.remove(0);
this.notifyAll();
System.out.println("pop="+list.size());
}catch(InterruptedException e){
e.printStackTrace();
}
return returnString;
}
}
P.java
public class P {
private MyStack mystack;
public P(MyStack mystack) {
super();
this.mystack=mystack;
}
public void pushServer(){
mystack.push();
}
}
C.java
public class C {
private MyStack mystack;
public C(MyStack mystack) {
super();
this.mystack=mystack;
}
public void popServer(){
System.out.println("pop= "+mystack.pop());
}
}
P_Thread.java
public class P_Thread extends Thread{
private P p;
public P_Thread(P p) {
super();
this.p=p;
}
public void run(){
while(true){
p.pushServer();
}
}
}
C_Thread.java
public class C_Thread extends Thread{
private C c;
public C_Thread(C c) {
super();
this.c=c;
}
public void run(){
while(true){
c.popServer();
}
}
}
Run.java
public static void main(String[] args){
MyStack mystack=new MyStack();
P p1=new P(mystack);
P p2=new P(mystack);
P p3=new P(mystack);
P p4=new P(mystack);
P p5=new P(mystack);
C c1=new C(mystack);
C c2=new C(mystack);
C c3=new C(mystack);
C c4=new C(mystack);
C c5=new C(mystack);
P_Thread a1=new P_Thread(p1);
P_Thread a2=new P_Thread(p2);
P_Thread a3=new P_Thread(p3);
P_Thread a4=new P_Thread(p4);
P_Thread a5=new P_Thread(p5);
a1.start();
a2.start();
a3.start();
a4.start();
a5.start();
C_Thread b1=new C_Thread(c1);
C_Thread b2=new C_Thread(c2);
C_Thread b3=new C_Thread(c3);
C_Thread b4=new C_Thread(c4);
C_Thread b5=new C_Thread(c5);
b1.start();
b2.start();
b3.start();
b4.start();
b5.start();
}
}