(wait / notify)方法实现生产者-消费者模型
任何一个对象都拥有一个线程等待池
挂在同一个对象的线程池中的线程之间可以互相唤醒
所以wait / notify 方法是属于Object类的
wait方法的使用必须放在synchronized同步快中
一、生产者类 / 消费者类 来实现 生产者-消费者 模型
生产者类:
class WaitSend implements Runnable{
boolean flag;
int theValue;
@Override
public void run() {
for (int i = 0; i < 5; i++) {
synchronized (this) {
while(flag){ //为什么需要用while 存在中断和假唤醒
try {
this.wait(); //wait方法会释放同步的钥匙
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//生产食物
theValue = new Random().nextInt(1000);
System.out.println("send the value is:"+theValue);
//自己去等待
flag = true;
//唤醒消费者
this.notify();
}
}
}
}
消费者类:
class WaitRec implements Runnable{
private WaitSend send;
public WaitRec(WaitSend send) {
super();
this.send = send;
}
@Override
public void run() {
//不知道生产者生产多少食物,生产多少消费多少
while(true){
synchronized (send) {
while(!send.flag){
try {
send.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//进行消费
System.out.println("reciver the value is:"+send.theValue);
//自己去等待
send.flag = false;
//唤醒对方
send.notify();
}
}
}
}
主方法:
public static void main(String[] args) {
WaitSend send = new WaitSend();
WaitRec rec = new WaitRec(send);
Thread t1 = new Thread(send);
Thread t2 = new Thread(rec);
//把t2设置成守护线程,当程序只有守护线程运行的时候,程序自动结束
t2.setDaemon(true);
t1.start();
t2.start();
}
二、Business类 来实现 生产者-消费者 模型
Business类:
class Business{
private int theValue;
private boolean flag;
//生产者方法
public void send(){
for (int i = 0; i < 5; i++) {
synchronized (this) {
while(flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//生产商品
theValue = new Random().nextInt(1000);
System.out.println("send the value is:"+theValue);
//自己去等待
flag = true;
//唤醒对方
this.notify();
}
}
}
//消费者方法
public void rec(){
while(true){
synchronized (this) {
while(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费商品
System.out.println("reciver the value is:"+theValue);
//自己去等待
flag = false;
//唤醒对方
this.notify();
}
}
}
}
主方法:
public static void main(String[] args) {
Business business = new Business();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
business.send();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
business.rec();
}
});
t1.start();
t2.start();
}
注意:
还有一种线程间数据通讯的方法
就是用lock和condition
condition.await();
condition.signal();
这是java5引入的线程机制java.util.concurrent
java.util.concurrent.locks