2.什么是线程间的通信 ?怎么实现线程通信

2.什么是线程间的通信 ?怎么实现线程通信2.1什么是线程通信以及实现步骤线程间通信的模型有两种:共享内存和消息传递线程通信其实就是,实现线程的交替工作,并传递信息线程间的通信具体步骤:(涉及上中下部)创建资源类,在资源类中船舰属性和操作方法 在资源类操作方法:判断、操作、通知 创建多个线程,调用资源类的操作方法 防止虚拟唤醒问题(if判读,只会判断一次)2.2synchronized案例操作线程的时候,等待线程使用wait()通知另外的线程操作用notify()、notifyAll()假设…

大家好,又见面了,我是你们的朋友全栈君。

   2.1什么是线程通信以及实现步骤

线程间通信的模型有两种:共享内存和消息传递
  线程通信其实就是 ,实现线程的交替工作,并传递信息

线程间的通信具体步骤:(涉及上中下部)

  1. 创建资源类,在资源类中船舰属性和操作方法
  2. 在资源类操作方法:判断、操作、通知
  3. 创建多个线程,调用资源类的操作方法
  4. 防止虚拟唤醒问题 (if 判读,只会判断一次)

2.2 synchronized案例

操作线程的时候,等待线程使用wait()
通知另外的线程操作用notify()、notifyAll()
假设有两个线程,该线程在执行过程中,判断值(不是该值等待,让其他线程抢),操作值,通知另外一个线程的调度

实现两个线程  对num  这个值操作,一个线程加1,一个线程减1,交替实现多次

//第一步 创建资源类,定义属性和操作方法
class Share {
    //初始值
    private int num = 0;
    //+1的方法
    public synchronized void incr() throws InterruptedException {
        //第二步 判断 干活 通知
       if(number != 0) { //判断number值是否是0,如果不是0,等待
            this.wait(); //在哪里睡,就在哪里醒
        }
        //如果number值是0,就+1操作
        number++;
        System.out.println(Thread.currentThread().getName()+" :: "+num);
        //通知其他线程
        this.notifyAll(); //注意这里的通知是随机的,就是只能通知全部
    }

    //-1的方法
    public synchronized void decr() throws InterruptedException {
        //判断
        if(number != 1) {
            this.wait();
        }
        //干活
        number--;
        System.out.println(Thread.currentThread().getName()+" :: "+number);
        //通知其他线程
        this.notifyAll();
    }
}

public class ThreadDemo1 {
    //第三步 创建多个线程,调用资源类的操作方法
    public static void main(String[] args) {
        Share share = new Share();
        //创建线程
        new Thread(()->{
            for (int i = 1; i <=10; i++) {
                try {
                    share.incr(); //+1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"AA").start();

        new Thread(()->{
            for (int i = 1; i <=10; i++) {
                try {
                    share.decr(); //-1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"BB").start();
    }
}

   可以看到,这时,代码是交替进行的 一个 +1 一个线程 -1

但是我们考虑如果同时 ,分别两个线程做加减,那会怎么样呢?

2.什么是线程间的通信 ?怎么实现线程通信

 虚假唤醒 :  wait  是在哪里睡,在哪里被唤醒只做了一次判断   虚假唤醒 放在while   if 判断,只   会判断一次 所以改为while ;循环判断,就会解决虚假唤醒;从而解决这个错误

2.3 Lock案例

使用lock先要创建锁的对象以及通知的对象
放置在资源类中


    private Lock lock= new ReentrantLock();   //创建可重锁
    private Condition  condition= lock.newCondition();
        //他能操作的对象

上锁 lock.lock();
解锁 lock.unlock();
以下都为 condition类:
唤醒所有等待的线程signalAll(),带上类名condition.signalAll();
唤醒一个等待线程signal(),带上类名,condition.signal();
造成当前线程在接到信号或者被中断之前一直处于等待状态await(),带上类名,condition.await();
 

Lock 实现的代码基本是相同的,注意上锁 和解锁 是自己手动 做的工作,最终都要在finally 解锁

   如果不解锁,会影响下面以后的线程

class LShare{
//这是共享资源,注意锁的创建和使用,其他的和上面基本相同
    private int num=0;

    private Lock lock= new ReentrantLock();   //创建可重锁
    private Condition  condition= lock.newCondition();

    //创建操作的方法
    public void add (){
        lock.lock();   //首先 手动上锁;
        try {  //判断,干活,通知
            while (num!=0){
                condition.await();
                //它使用的是这个对象 调用方法 等待
            }
         num++;
            System.out.println( Thread.currentThread().getName()+" 干活完成 :"+num);
            condition.signalAll(); //这个通知方法
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
           lock.unlock(); //最终不管出现什么错误,都会解锁
        }
    }

这就实现了线程间的通信,,即 他们能够根据 信息,完成交替的工作

     下面就是学如何 定制通信?(交替进行线程,但是每个线程的 工作是改变的)

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/160492.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • 十大经典排序算法详解(三)-堆排序,计数排序,桶排序,基数排序[通俗易懂]

    十大经典排序算法详解(三)-堆排序,计数排序,桶排序,基数排序[通俗易懂]十大经典排序算法-堆排序,计数排序,桶排序,基数排序1-堆排序算法思想:算法图解:示例代码:在这里插入代码片复杂度分析:2-计数排序算法思想:算法图解:示例代码:在这里插入代码片复杂度分析:3-桶排序算法思想:算法图解:示例代码:在这里插入代码片复杂度分析:4-基数排序算法思想:算法图解:示例代码:在这里插入代码片复杂度分析:…

    2022年7月12日
  • sqrt()函数的详解和用法「建议收藏」

    sqrt()函数的详解和用法「建议收藏」sqrt()函数是我们经常使用的一个函数。下面我就详细的介绍它的一些用法和使用规范所需的头文件#include<math.h>函数原型doublesqrt(doublex);作用:sqrt()用来求给定值的平方根常见的使用错误输出36的开根号忽略了sqrt()函数的返回值是double型。导致出错解决办法如下:常见的使用sqrt()函数的规范写法例如:我们要判断一个数是不是质数,只需要判断2~n开根号之间有没有可以整除的数就可以了错误的.

    2022年6月10日
  • nginx启动命令和停止命令(linux重启nginx)

    进入nginx所在目录:打开cmd命令窗口,进入nginx所在目录。在nginx所在目录下执行nginx启动、停止命令。nginx启动命令:【startnginx】或【nginx.exe】nginx停止命令:【nginx.exe-squit】或【nginx.exe-sstop】…

    2022年4月13日
  • Vue学习之样式处理[通俗易懂]

    Vue学习之样式处理[通俗易懂]Vue学习之样式处理

    2022年4月23日
  • 触发OSR 编译(以goto指令为例)及安装与卸载

    触发OSR 编译(以goto指令为例)及安装与卸载

    2020年11月20日
  • slam技术前景_哄哄什么

    slam技术前景_哄哄什么原标题:牛逼哄哄的SLAM技术即将颠覆哪些领域?什么是SLAM?机器人在未知环境中,要实现智能化需要完成三个任务,第一个是定位(Localization),第二个是建图(Mapping),第三个则是随后的路径规划(Navigation)。之前地平线的高翔博士用这样一句话概括SLAM的释义。不过实际生活中的SLAM都是和激光雷达或者单目/双目摄像头结合的形式出现在我们面前的,有时甚至跟更多的…

    2022年9月30日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号