您的位置:首页 > 其它

多线程——用Lock(锁)和Condition(监听器)来优化生产者消费者模式(进一步优化,解决可能产生的死锁问题)

2016-08-20 16:19 309 查看
package com.qianfeng.demo02 ;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* 之前解决本方唤醒对方的问题是唤醒了线程池中全部线程。
* 缺点:这样做可以实现,但是效率比较低,而且还唤醒了本方。
*
* 升级之后lock和condition就能解决这个问题。
* 之前是两个锁嵌套可能出现死锁的问题,现在的解决方案是只有一个锁,但是锁上面可以加入多个监视器。
* 一个用来监视生成者,一个用来监视消费者。
*
* */
//资源
class Resource{
private String name;
private int count = 1;
private boolean flag;  //判断盘子里是否有馒头的标志位。
//指定一把锁
private Lock lock = new ReentrantLock();
//获取锁的监视器
private Condition pro_con = lock.newCondition();   //负责监视生产者
private Condition cus_con = lock.newCondition();   //负责监视消费者
public void set(String name){
//获取锁
lock.lock();
try {
while (flag) {
try {
pro_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"....生产了..."+this.name);

flag = true;
cus_con.signal();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();    //释放锁
}
}

public  void get(){
lock.lock();
try {
while (!flag) {
try {
cus_con.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"....消费了..."+this.name);
flag = false;
pro_con.signal();
} catch (Exception e) {
// TODO: handle exception
}finally {
lock.unlock();
}
}
}
//生产者
class Produce implements Runnable{
private Resource  r;

public Produce (Resource  r) {
this.r = r;
}

@Override
public void run() {
while (true) {
r.set("馒头");
}
}
}
//消费者
class Customer  implements Runnable{
private Resource  r;

public Customer (Resource  r) {
this.r = r;
}

@Override
public void run() {
while (true) {
r.get();
}
}
}
public class LockDemo02  {

public static void main(String[] args) {
Resource  r = new Resource ();

Produce  p = new Produce (r);
Customer  c = new Customer (r);

Thread t0 = new Thread(p);
Thread t1 = new Thread(p);
Thread t  = new Thread(c);
Thread t3 = new Thread(c);

t0.start();
t1.start();
t .start();
t3.start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程
相关文章推荐