• 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();
        }
    
    }

    编译运行:

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

  • 相关阅读:
    Selenium WebDriver使用IE浏览器(转)
    webdriver调用ie浏览器报错
    webdriver调用chrome浏览器
    WebDriver 调用ie浏览器报错(转)
    Eclipse上安装GIT插件EGit及使用(转)
    webDriver 退出浏览器(转)
    JMeter csv文件参数化
    不同目录存在相同名称的py文件,执行时,报错的解决方法
    python+requests传两种参数体
    JMeter 请求参数
  • 原文地址:https://www.cnblogs.com/webor2006/p/8413286.html
Copyright © 2020-2023  润新知