您的位置:首页 > 编程语言 > Java开发

java 线程间通信,多生产者多消费者问题

2017-11-15 10:46 441 查看

java 线程间通信,多生产者多消费者问题

/**
* 多生产者,多消费者的问题
* if判断标记,只判断一次,会导致不该 运行的线程运行了,出现 了数据错误 的情况
* while判断标记,解决了线程获取执行权后,是否要运行
*
*
* notify:只能唤醒一个线程,如果 本方唤醒 了本方,没有意义 ,而且 while 判断标记 + notify会导致死锁
* notifyAll:解决了本方线程一定会唤醒对方线程的问题
*
* jdk1.5以后将同步 和锁封装成了对象 ,并将操作锁的隐式方式 定义 到了该 对象 中,
* 将隐式动作变成 了显示 动作
*
*
*
* Lock接口:出现替代了同步代码块或者同步函数,将同步的隐式锁操作变成 现实锁操作
* 同时更为灵活,可以一个锁上加上多组监视器
* lock():获取锁
* unlock():释放锁,通常需要定义finally代码块中
*
* Condition接口:出现 替代 了Object中的wait notify notifyAll方法
*                将这些监视器方法单独进行了封装,变成 Condition监视器对象
*                可以任意锁进行组合
* await();signal();signlAll()
*/
class Resource{
private String name;
private int count = 1;
private boolean flag;

//创建一个锁对象
Lock lock = new ReentrantLock();
//通过已有的锁获取该锁上的监视器对象
Condition condition = lock.newCondition();

//通过 已有的锁获取两组监视器,一级监视生产者,一组监视消费者
Condition pro_con = lock.newCondition();
Condition consumer_con = lock.newCondition();

public  void set3(String name){
lock.lock();
try {

while (flag){
try {
//                    this.wait();
//                    condition.await();
pro_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"..生产者..."+this.name);
flag = true;
//            notifyAll();
//            condition.signalAll();
consumer_con.signal();
}finally {
lock.unlock();
}

}

public synchronized void out3(){
lock.lock();
try {
while (!flag){
try {
//                    this.wait();
//                    condition.await();
consumer_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+".......消费者........"+this.name);
flag = false;
//            notifyAll();
//            condition.signalAll();
pro_con.signal();
}finally {
lock.unlock();
}

}

public  void set2(String name){
lock.lock();
try {
//            if (flag)  这里以前用的是if,会发生安全问题
while (flag){
try {
//                    this.wait();  第一次的用法
condition.await();
//                    pro_con.await();第三次的用法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"..生产者..."+this.name);
flag = true;
//            notifyAll();第一次的用法
//            condition.signalAll();第三次的用法
consumer_con.signal();
}finally {
lock.unlock();
}

}

public synchronized void out2(){
lock.lock();
try {
while (!flag){
try {
//                    this.wait();第一次的用法
condition.await();
//                    consumer_con.await();第三次的用法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+".......消费者........"+this.name);
flag = false;
//            notifyAll();
//            condition.signalAll();
pro_con.signal();
}finally {
lock.unlock();
}

}
public synchronized void set(String name){
// if (flag)  这里以前用的是if,会发生安全问题
while (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"..生产者..."+this.name);
flag = true;
notifyAll();
}
public synchronized void out(){
while (!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+".......消费者........"+this.name);
flag = false;
notifyAll();
}
}

class prodeucer implements Runnable{

private Resource resource;

public prodeucer(Resource resource) {
this.resource = resource;
}

@Override
public void run() {
while (true){
resource.set("烤鸭");
}
}
}
class consumer implements Runnable{

private Resource resource;

public consumer(Resource resource) {
this.resource = resource;
}

@Override
public void run() {
while (true) {
resource.out();
}
}
}

public class ProducerConsumerDemo {
public static void main(String[] args){
Resource resource = new Resource();
prodeucer prodeucer = new prodeucer(resource);
consumer consumer = new consumer(resource);
Thread t0 = new Thread(prodeucer);
Thread t1 = new Thread(prodeucer);
Thread t2 = new Thread(consumer);
Thread t3 = new Thread(consumer);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: