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(); //最终不管出现什么错误,都会解锁
        }
    }

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

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

 

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

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