JAVA原生线程协同机制

java原生的线程协同机制

线程协同.png
  • blocked: 需要获得锁,从runnable->blocked;
    获得锁blocked->runnable;
  • waiting: java线程为了协调各个线程工作的一种特殊方式;(ps:1.0就已经存在)
    (time waiting是waiting的一种特殊机制,待超时等待)

举例:

  • 线程 :一个工人
  • 代码 :一份说明书
  • 同步对象 :一个印章
  • wait() :拿到印章,把自己的名字加入等待队列,然后把印章放回去
  • notify() : 拿到印章,挑一个等待队列的人通知一下
  • notifyAll() : 拿到印章,把等待队列的人全部通知一下

注意: 一定要和一个对象(monitor)协同

[面试题]wait和sleep有什么区别?

  • wait放弃印章(放弃资源);sleep趴在印章上睡着了(不放弃资源);

实现消费者/生产者模型

public class Main {
    public static void main(String[] args) throws InterruptedException {
        // 生产一个,消费一个,交替循环
        Container container = new Container();
        Producer producer = new Producer(container);
        Consumer consumer = new Consumer(container);

        producer.start();
        consumer.start();

        producer.join();
        consumer.join();
    }

    static class Container extends Thread {
        Object value;
    }

    static class Producer extends Thread {
        Container container;

        public Producer(Container container) {
            this.container = container;
        }


        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (container) {
                    // 若条件不满足,就等待
                    while (null != container.value) {
                        try {
                            container.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }

                    //条件满足就生产,并通知别人
                    int random = new Random().nextInt();
                    System.out.println("Producing " + random);

                    container.value = random;
                    container.notify();
                }
            }
        }
    }

    /**
     * 消费者与生产者完全相反
     */
    static class Consumer extends Thread {
        Container container;

        public Consumer(Container container) {
            this.container = container;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (container) {
                    // 若条件不满足,就等待
                    while (null == container.value) { //不能使用if()条件进行判断,因为存在中断或者虚假唤醒,所以为了在不满足条件的时候还能够继续sleep,不能用if()判断 (存在虚假唤醒的原因: java线程调度完全取决于CPU,所以在CPU与操作系统层面上存在虚假唤醒)
                        try {
                            container.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }

                    //条件满足就消费,并通知别人
                    System.out.println("Consuming " + container.value);

                    container.value = null;
                    container.notify();
                }
            }
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容