当多个线程使用同一资源时候会造成死锁,此时,可以使用生产者消费者模式来避免线程死锁
标志位来做信号灯控制线程防止deadlock
- flag-true:生产者生产,消费者等待,生产完成后,通知消费
- flag-false:消费者消费,生产者等待,消费完成后,通知生产
在模拟中,share类模拟共享资源,如果flag位true,则this.wait(),声场完成后,notify()后,置flag为false这样消费者不等待直接消费,消费后notify(),置flag 为true这样生产者不等待直接生产。
package TreadLearning;
/**
* 采用生产者消费者模式,信号灯法
* wait()等待,释放锁
* notify/notifyall
* @author 袁盛桐
*
*/
public class ProdConsuAvoidDeadlock {
public static void main(String[] args) {
share demo = new share();
producer p = new producer(demo);
consumer c = new consumer(demo);
new Thread(p).start();
new Thread(c).start();
}
}
/**
* 一个场景中多线程共享的资源
* @author 袁盛桐
*
*/
class share{
private String source;
//标志位来做信号灯控制线程防止deadlock
//flag-true:生产者生产,消费者等待,生产完成后,通知消费
//flag-false:消费者消费,生产者等待,消费完成后,通知生产
private boolean flag = true;
public synchronized void produce(String source,int num) {
if(!flag) {
try {
this.wait();//等待
}catch (Exception e) {
e.printStackTrace();
}
}
//模拟开始生产
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
//生产完毕
this.source = source;
System.out.println("produce finish:"+source+num);
//通知消费
this.notify();
//生产者停下
this.flag = false;
}
public synchronized void consume(int num) {
if(flag) {
try {
this.wait();//等待
} catch (Exception e) {
e.printStackTrace();
}
}
//模拟开始消费
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
//消费完毕
System.out.println("consume finish:"+source+num);
//通知生产
this.notify();
//消费停止
this.flag = true;
}
}
/**
* 模拟生产者
* @author 袁盛桐
*
*/
class producer implements Runnable{
private share share;
public producer(TreadLearning.share share) {
super();
this.share = share;
}
@Override
public void run() {
for(int i=0; i<20; i++) {
if(0 == i%2) {
share.produce("left",i);
}else {
share.produce("right",i);
}
}
}
}
/**
* 模拟消费者
* @author 袁盛桐
*/
class consumer implements Runnable{
private share share;
public consumer(share share) {
super();
this.share = share;
}
@Override
public void run() {
for(int i=0; i<20; i++) {
share.consume(i);
}
}
}