学习java多线程的synchronized关键字与wait/notify等待唤醒机制。
又想到了操作系统里的消费者与生产者模式,写了个小例子加深理解。
共享资源为Food类
代码如下:
public class Food {
private int count;//生产者与消费者共享的资源,假设最大值为5
public Food() {
}
public synchronized int getCount() {
return count;
}
public synchronized void setCount(int count) {
this.count = count;
}
}
生产者类:
public class Producer extends Thread {
private Food f;
public Producer(Food f) {
this.f = f;
}
public void run() {
synchronized(f) {
try {
if(f.getCount()>5) f.wait();//食物超过5就不能再生产了
if(f.getCount()>0) f.notify();//食物大于0,通知消费者或生产者干活
if(f.getCount()<5)//食物小于5,可以继续生产
f.setCount(f.getCount()+1);
System.out.println("生产者线程:食物还剩"+f.getCount()+"个");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
消费者类:
public class Consumer extends Thread{
private Food f;
public Consumer(Food f) {
this.f = f;
}
public void run() {
synchronized(f) {
try {
if(f.getCount()<=0) f.wait();//没有食物,不能消费,阻塞起来
if(f.getCount()<5) f.notify();//食物小于5,通知生产者或消费者干活
if(f.getCount()>0)//食物大于0,可以消费
f.setCount(f.getCount()-1);
System.out.println("消费者线程:食物还剩"+f.getCount()+"个");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Food f = new Food();
f.setCount(5);//初始食物设定为5个
Producer p = new Producer(f);
Thread p1 = new Thread(p);
Thread p2 = new Thread(p);
Thread p3 = new Thread(p);
Thread p4 = new Thread(p);
Thread p5 = new Thread(p);
Consumer c = new Consumer(f);
Thread c1 = new Thread(c);
Thread c2 = new Thread(c);
Thread c3 = new Thread(c);
Thread c4 = new Thread(c);
Thread c5 = new Thread(c);
c1.start();
c2.start();
c3.start();
c4.start();
c5.start();
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
}
}
运行结果如下:
消费者线程:食物还剩4个
消费者线程:食物还剩3个
消费者线程:食物还剩2个
生产者线程:食物还剩3个
生产者线程:食物还剩4个
消费者线程:食物还剩3个
消费者线程:食物还剩2个
生产者线程:食物还剩3个
生产者线程:食物还剩4个
生产者线程:食物还剩5个
--------------------
消费者线程:食物还剩4个
消费者线程:食物还剩3个
消费者线程:食物还剩2个
消费者线程:食物还剩1个
消费者线程:食物还剩0个
生产者线程:食物还剩1个
生产者线程:食物还剩2个
生产者线程:食物还剩3个
生产者线程:食物还剩4个
生产者线程:食物还剩5个
java中的wait()与操作系统的wait 不一样,再做一次理解。
操作系统中:
**wait:**通过信号量机制,申请一个资源,如果没有,线程进入阻塞状态。申请成功可以运行。
java中:
wait():释放当前的对象锁,线程进入阻塞状态,等待同一个对象调用notify或notifyAll()唤醒。
多个生产者与消费者假死现象:
当有多个生产者与消费者的时候,就如我程序中的那样,调用notify()方法,不一定唤醒的是“异类”(消费者唤醒生产者),可能是“同类”(生产者唤醒生产者)。
**解决办法假死办法:**用notifyAll()