ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JUC之线程间定制化通信

2022-01-01 21:34:42  阅读:198  来源: 互联网

标签:JUC lock signal await private 线程 定制 Condition


线程通信之定制化

之前文章中写了下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()

标签:JUC,lock,signal,await,private,线程,定制,Condition
来源: https://www.cnblogs.com/xbhog/p/15756158.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有