java线程基础巩固---线程间通信快速入门,使用wait和notify进行线程间的数据通信

之前已经对于线程同步相关的知识点进行了详细的学习,这次来学习一下线程间的通信相关的知识,话不多说直接用代码进行演练,以一个简陋的生产者消费者模型来初步了解下线程间通信是怎么一回事。

生产消费者第一版:

然后具体实现生产消费方法:

此时用两个线程来应用一下:

这时看一下运行结果:

对于一个生产者与一个消费者理解情况应该是生产一个之后则立马被消费掉,以此不断循环,也就是生产一个消费一个,那为啥目前这个极其初级版本的生产消费者的模型没有如咱们的预期呢?答案就是:没有线程之间的通信协作,对于生产者来说它不知道有人消费了,而对于消费者来说它也不知道有人生产了,所以此时线程间的通信场景就诞生了,下面来看加入线程通信之类的改良版本。

生产消费者第二版:

接着来看生产方法:

这里需要注意一个细节,其中的"Lock.wait()"并非是指Thread中的wait(),而是指的Object.wait(),如下:

同样的消费者也得根据这个标识做类似的处理,如下:

另外对于生产者而言,也需要在生产了之后通知正在等待的消费者,如下:

接下来测试一下:

package com.javaconcurrency.threadcommunication;

public class ProductConsumerVersion2 {
    private final Object LOCK = new Object();
    private int i = 1;
    /* 此标识用来说明是否当前已经生产过了,默认没有 */
    private volatile boolean isProduced = false;

    private void product() {
        synchronized (LOCK) {
            if (isProduced) {
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                i++;
                System.out.println("P->" + i);
                LOCK.notify();
                isProduced = true;
            }
        }
    }

    private void comsume() {
        synchronized (LOCK) {
            if (isProduced) {
                System.out.println("C->" + i);
                LOCK.notify();
                isProduced = false;
            } else {
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        ProductConsumerVersion2 productConsumerVersion2 = new ProductConsumerVersion2();

        new Thread("P") {
            @Override
            public void run() {
                while (true)
                    productConsumerVersion2.product();
            }
        }.start();

        new Thread("C") {
            @Override
            public void run() {
                while (true)
                    productConsumerVersion2.comsume();
            }
        }.start();
    }

}

编译运行:

貌似挺完美的,但是!!依然存在缺陷,现在是只有一个生产者和一个消费者,如果有多个生产者与多个消费者的话那就有问题啦,这个在下次再继续改善~

posted on 2018-02-04 15:28  cexo  阅读(262)  评论(0编辑  收藏  举报

导航