生产消费者问题是经典的问题
我有一个箱子,可以放苹果,有一个生产者生产苹果,一个消费者消费苹果,用线程可以这样写:
/*箱子*/
class PT {
private String info="苹果";
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
/*生产者*/
class MyThread9 implements Runnable {
private PT pt;
public MyThread9(PT pt) {
this.pt = pt;
}
@Override
public void run() {
for(int i = 0; i<10; i++) {
System.out.println("生产:苹果");
pt.setInfo("苹果");
}
}
}
/*消费者*/
class MyThread10 implements Runnable {
private PT pt;
public MyThread10(PT pt) {
this.pt = pt;
}
@Override
public void run() {
for(int i = 0; i<10; i++) {
System.out.println("消费:" + pt.getInfo());
}
}
}
public class test5 {
public static void main(String ar[]) {
PT pt = new PT();
MyThread9 m = new MyThread9(pt);
MyThread10 m1 = new MyThread10(pt);
Thread t1 = new Thread(m,"生产者");
Thread t2 = new Thread(m1,"消费者");
t1.start();
t2.start();
}
}
而这样的结果,会出问题,如果我的箱子只能放一个苹果,那么就只有
箱子为空,生产者才能放苹果,
箱子不为空,消费者才能取苹果
而程序运行的结果:
会出现一直放,或者一直取,这样明显不符合逻辑。
要解决这个问题,需要用到Object类的方法:
例子:
/*箱子*/
class PT {
private String info="苹果";
/*箱子为空的标记*/
private boolean flag = false;
public synchronized void get() {
if(flag) {
/*箱子为空,当前线程等待,等到箱子不为空时会被唤醒*/
try {
super.wait();
} catch(Exception e) {e.printStackTrace();}
} else {
/*箱子不为空,取走苹果*/
System.out.println("消费:"+info);
/*标记箱子为空*/
flag = true;
/*唤醒线程*/
super.notify();
}
}
public synchronized void setInfo(String info) {
if(!flag) {
/*如果箱子不为空,则生产者线程等待,等待箱子为空的时候会被唤醒*/
try {
super.wait();
} catch(Exception e){e.printStackTrace();}
}
else {
/*箱子为空,可以生产*/
this.info = info;
System.out.println("生产:苹果");
/*标记箱子不为空*/
flag = false;
/*唤醒等待的线程*/
super.notify();
}
}
}
/*生产者*/
class MyThread9 implements Runnable {
private PT pt;
public MyThread9(PT pt) {
this.pt = pt;
}
@Override
public void run() {
for(int i = 0; i<10; i++) {
pt.setInfo("苹果");
}
}
}
/*消费者*/
class MyThread10 implements Runnable {
private PT pt;
public MyThread10(PT pt) {
this.pt = pt;
}
@Override
public void run() {
for(int i = 0; i<10; i++) {
pt.get();
}
}
}
public class test5 {
public static void main(String ar[]) {
PT pt = new PT();
MyThread9 m = new MyThread9(pt);
MyThread10 m1 = new MyThread10(pt);
Thread t1 = new Thread(m,"生产者");
Thread t2 = new Thread(m1,"消费者");
t2.start();
t1.start();
}
}
结果:
这样就能解决生产者消费者问题
至于notify()与notifyAll()的区别,你可以理解为,
notify()是有序的唤醒,
notifyAll()是无序的唤醒,唤醒后谁的优先级高,谁就更有可能先执行。