• JUC之线程间定制化通信


     

    之前文章中写了下Condition的使用,这里我们详细说下其中的用法:

    首先使用Condition需要实例化Lock

    private Lock lock = new ReentrantLock();   //创建锁
    

    使用lock里面的newCondition方法创建Condition对象:

    private Condition c1 = lock.newCondition();
    

    其优点:比synchronized更安全、更高效。

    选自:廖雪峰的官网-Java教程

    Condition提供的await()signal()signalAll()原理和synchronized锁对象的wait()notify()notifyAll()是一致的,并且其行为也是一样的:

    • await()会释放当前锁,进入等待状态;
    • signal()会唤醒某个等待线程;
    • signalAll()会唤醒所有等待线程;
    • 唤醒线程从await()返回后需要重新获得锁。

    需要注意的是上面signal\signalAll与await方法的对应关系;

    通过一个例子来理解线程间的定制化:

    要求:

    image-20211230213747403

    实现代码:

    package com.JUC;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    //线程间的定制化通信
    class ShareRewsource {
        private int flag = 1;  //1表示线程AAA,2表示线程BBB,3表示线程CCC
    
        private Lock lock = new ReentrantLock();   //创建锁
        //代替Object中的等待、唤醒等操作,更加的安全高效
        private Condition c1 = lock.newCondition();  //对标AAA线程
        private Condition c2 = lock.newCondition();  //对标BBB线程
        private Condition c3 = lock.newCondition();  //对标CC线程
    
        //创建方法
        public void print5(int loop) {
            lock.lock();
            try {
                while (flag != 1) {
                    c1.await();
                }
                //操作
                for (int i = 1; i <= 5; i++) {
                    System.out.println(Thread.currentThread().getName() + "-----" + i + "::" + loop);
                }
                flag = 2;
                c2.signal();  //通知BBB线程  唤醒BBB线程,唤醒后在BBB线程的await后继续执行;
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
    
        }
    
        //创建方法
        public void print10(int loop) {
            lock.lock();
            try {
                while (flag != 2) {
                    c2.await();
                }
                //操作
                for (int i = 1; i <= 10; i++) {
                    System.out.println(Thread.currentThread().getName() + "-----" + i + "::" + loop);
                }
                flag = 3;
                c3.signal();  //通知CCC线程
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
    
        }
    
        //创建方法
        public void print15(int loop) {
            lock.lock();
            try {
                while (flag != 3) {
                    c3.await();
                }
                //操作
                for (int i = 1; i <= 15; i++) {
                    System.out.println(Thread.currentThread().getName() + "-----" + i + "::" + loop);
                }
                flag = 1;
                c1.signal();  //通知AAA线程
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
    
        }
    
    }
    
    public class ThreadPrivateDemo {
        public static void main(String[] args) {
            ShareRewsource rewsource = new ShareRewsource();
            new Thread(() -> {
                for (int i = 1; i <= 10; i++) {
                    rewsource.print5(i);
                }
            }, "AAA").start();
            new Thread(() -> {
                for (int i = 1; i <= 10; i++) {
                    rewsource.print10(i);
                }
            }, "BBB").start();
            new Thread(() -> {
                for (int i = 1; i <= 10; i++) {
                    rewsource.print15(i);
                }
            }, "CCC").start();
        }
    }
    

    其中对应关系:注意唤醒和等待所在的代码段

    c2.signal() --> c2.await()

    c3.signal() --> c3.await()

    c1.signal() --> c1.await()

    因为相信,所以看见.
  • 相关阅读:
    小白必读:闲话HTTP短连接中的Session和Token
    网络编程懒人入门(六):深入浅出,全面理解HTTP协议
    IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?
    致我们再也回不去的 Github ...
    了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化
    网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门
    盘点微信的前世今生,微信成功的必然和偶然
    微信七年回顾:历经多少质疑和差评,才配拥有今天的强大
    写给小白的实时音视频技术入门提纲
    jenkins使用jacoco插件检测代码覆盖率(八)
  • 原文地址:https://www.cnblogs.com/zeenzhou/p/15769449.html
Copyright © 2020-2023  润新知