zoukankan      html  css  js  c++  java
  • 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()

  • 相关阅读:
    Leetcode 538. Convert BST to Greater Tree
    Leetcode 530. Minimum Absolute Difference in BST
    Leetcode 501. Find Mode in Binary Search Tree
    Leetcode 437. Path Sum III
    Leetcode 404. Sum of Left Leaves
    Leetcode 257. Binary Tree Paths
    Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
    Leetcode 226. Invert Binary Tree
    Leetcode 112. Path Sum
    Leetcode 111. Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/xbhog/p/15756158.html
Copyright © 2011-2022 走看看