java多线程(2)-实现生产者/消费者模式

来源:互联网 发布:php域名授权管理系统 编辑:程序博客网 时间:2024/06/06 12:43

实现生产者/消费者一对一交替打印

package cn.limbo.thread.ConditionDemo;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * <B>功能简述</B><br> * 实现生产者/消费者模式:一对一交替打印 * * @date 2017/12/15 */public class MyService {    //ReentrantLock对象的创建    private Lock lock = new ReentrantLock();    //newCondition 对象可以更好的实现线程的等待和唤醒    private Condition condition = lock.newCondition();    private boolean hasValue = false;    public void set() {        try {            lock.lock();            while (hasValue) {                condition.await();            }            System.out.println(" 打印*+ ");            hasValue = true;            condition.signal();        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }    public void get() {        try {            lock.lock();            while (!hasValue) {                condition.await();            }            System.out.println(" 打印*- ");            hasValue = false;            condition.signal();        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }}class MyThreadA extends Thread {    private MyService myService;    public MyThreadA(MyService myService) {        super();        this.myService = myService;    }    @Override    public void run() {        for (int i = 0; i < Integer.MAX_VALUE; i++) {            myService.set();        }    }}class MyThreadB extends Thread {    private MyService myService;    public MyThreadB(MyService myService) {        super();        this.myService = myService;    }    @Override    public void run() {        for (int i = 0; i < Integer.MAX_VALUE; i++) {            myService.get();        }    }}class Run{    public static void main(String[] args) {        MyService service = new MyService();        MyThreadA myThreadA = new MyThreadA(service);        myThreadA.start();        MyThreadB threadB = new MyThreadB(service);        threadB.start();    }}

多对多交替打印

package cn.limbo.thread.ConditionM2MDemo;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by lhh on 2017/12/18. */public class MyService {    private Lock lock = new ReentrantLock();    private Condition condition = lock.newCondition();    private boolean hasValue = false;    public void set() {        try {            lock.lock();            while (hasValue) {                System.out.println(" 有可能**+连续");                condition.await();            }            System.out.println(" 打印*+ ");            hasValue = true;            condition.signal();        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }    public void get() {        try {            lock.lock();            while (!hasValue) {                System.out.println(" 有可能**-连续");                condition.await();            }            System.out.println(" 打印*- ");            hasValue = false;            condition.signal();        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }}class MyThreadA extends Thread {    private MyService myService;    public MyThreadA(MyService myService) {        super();        this.myService = myService;    }    @Override    public void run() {        for (int i = 0; i < Integer.MAX_VALUE; i++) {            myService.set();        }    }}class MyThreadB extends Thread {    private MyService myService;    public MyThreadB(MyService myService) {        super();        this.myService = myService;    }    @Override    public void run() {        for (int i = 0; i < Integer.MAX_VALUE; i++) {            myService.get();        }    }}class Run {    public static void main(String[] args) {        MyService service = new MyService();        MyThreadA[] myThreadAs = new MyThreadA[10];        MyThreadB[] myThreadBs = new MyThreadB[10];        for (int i = 0; i < 10; i++) {            myThreadAs[i] = new MyThreadA(service);            myThreadBs[i] = new MyThreadB(service);            myThreadAs[i].start();            myThreadBs[i].start();        }    }}

运行结果

发现程序处于假死状态,需要把MyService中的两处signal()代码改成signalAll()即可。但此时,signalAll()是唤醒所有线程那么被唤醒的很有可能是同类。