多线程通信(notify和wait升级CountDownLatch的使用)-----线程之间的实时通信

上一篇看了notify和wait的作用,给线程之间提供了通信,但是也是存在一定的弊端,就是不实时的问题,也就是当t1线程的notify()向t2线程发出通知,由于notify不释放锁,导致结果t1线程执行完毕后,t2线程才会去执行。我们要的效果是:当t2线程接收到通知以后t2线程就开始执行,而不是等待t1执行完毕后才执行。

咱们采用的办法是:使用CountDownLatch这个类

package com.wuk.Demo;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class MyThread005 {

    private static volatile List<String> list=new ArrayList<String>();  

    public void add() {

        list.add("wuk");
    }

    public  int size() {

        return list.size();
    }

    public static void main(String[] args) {

        final CountDownLatch countDownLatch=new CountDownLatch(1);//1表示通知一次就可以了countDownLatch.countDown();

        MyThread005 myList=new MyThread005();

        Thread t1=new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("t1线程启动。。。。");
                try {
                    for(int i=0;i<10;i++) {

                        myList.add();
                        System.out.println("线程"+Thread.currentThread().getName()+"向集合中添加一个元素了");
                        Thread.sleep(500);
                        if(myList.size()==5) {

                            System.out.println("线程"+Thread.currentThread().getName()+"已经发出通知。。。。。。。");

                            countDownLatch.countDown();
                        }
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        },"t1"); 

        Thread t2=new Thread(new Runnable() {

            @Override
            public void run() {

                try {
                    System.out.println("t2启动。。。");
                    if(myList.size()!=5) {
                        System.out.println("t2等待。。。。");
                        countDownLatch.await();
                    }
                    System.out.println("当前线程:" + Thread.currentThread().getName() + "收到通知线程停止..");
                    throw new RuntimeException();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        },"t2");


        t2.start();
        t1.start();
    }

}

打印结果:

t2启动。。。
t1线程启动。。。。
t2等待。。。。
线程t1向集合中添加一个元素了
线程t1向集合中添加一个元素了
线程t1向集合中添加一个元素了
线程t1向集合中添加一个元素了
线程t1向集合中添加一个元素了
线程t1已经发出通知。。。。。。。
线程t1向集合中添加一个元素了
当前线程:t2收到通知线程停止..
Exception in thread "t2" java.lang.RuntimeException
    at com.wuk.Demo.MyThread005$2.run(MyThread005.java:64)
    at java.lang.Thread.run(Unknown Source)
线程t1向集合中添加一个元素了
线程t1向集合中添加一个元素了
线程t1向集合中添加一个元素了
线程t1向集合中添加一个元素了

上面的打印可能有问题,就是:

线程t1已经发出通知。。。。。。。
线程t1向集合中添加一个元素了

这个是打印的问题,因为打印也需要时间,不用管它。

这样就达到我们想要的线程通信实时的效果了,也就是这边通知,那边马上就有响应了。

猜你喜欢

转载自blog.csdn.net/wu2374633583/article/details/80864957
今日推荐