• 玩转Java多线程(Lock.Condition的正确使用姿势)


    转载请标明博客的地址

    本人博客和github账号,如果对你有帮助请在本人github项目AioSocket上点个star,激励作者对社区贡献

    看到就是赚到,本博客只会贴出干货,欢迎光顾

    本篇讲的是lock.condition()的正确使用方式(也是之前看过的一篇,今天又把他实现出来)

    首先,代码逻辑规则如下:

          1.使用3个线程依次打印ABC

    直接上代码:

    package Thread;

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

    /**
    *
    * @ClassName: LockConditionTest
    * @Description:三个线程依次打印ABC
    * @author:  
    * @date: 2019年6月27日 下午4:31:41
    * @version 1.8.0
    * @param
    *
    */
    public class LockConditionTest{
    public static void main(String[] args) {
    final AlternateDemo ad = new AlternateDemo();
    new Thread(new Runnable() {
    @Override
    public void run() {
    for (int i = 0; i < 10; i++) {
    ad.loopA();
    }
    }
    }, "A").start();
    new Thread(new Runnable() {
    @Override
    public void run() {
    for (int i = 0; i < 10; i++) {
    ad.loopB();
    }
    }
    }, "B").start();
    new Thread(new Runnable() {
    @Override
    public void run() {
    for (int i = 0; i < 10; i++) {
    ad.loopC();
    System.out.println("-----------------------------------");
    }
    }
    }, "C").start();
    }
    }
    class AlternateDemo {
    private int number = 1; //当前正在执行线程的标记,相当于状态标记

    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();
    public void loopA() {
    lock.lock();
    try {
    //1. 判断
    if (number != 1) {
    condition1.await();
    }
    //2. 打印
    System.out.println(Thread.currentThread().getName());
    //3. 唤醒
    number = 2;
    condition2.signal();
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    lock.unlock();
    }
    }
    public void loopB() {
    lock.lock();
    try {
    //1. 判断
    if (number != 2) {
    condition2.await();
    }
    //2. 打印
    System.out.println(Thread.currentThread().getName());
    //3. 唤醒
    number = 3;
    condition3.signal();
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    lock.unlock();
    }
    }
    public void loopC() {
    lock.lock();
    try {
    //1. 判断
    if (number != 3) {
    condition3.await();
    }
    //2. 打印
    System.out.println(Thread.currentThread().getName());
    //3. 唤醒
    number = 1;
    condition1.signal();
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    lock.unlock();
    }
    }
    }

    总结:1.与wait对比,wait方式需要依赖synchronized代码块,而condtion.wait()依赖Lock对象,并且代码更加灵活

            2.condition.wait()可以将不同条件下的线程放入不同的等待队列,而单纯的wait()方法会将所有情况下的线程放入一个等待队列,这样在大量线程唤醒时会造成资源浪费

            3.使用Lock对象进行同步,这样线程同步只需要依赖Lock对象,而使用原始的synchronized(this){}进行同步,需要依赖当前对象,笔者更喜欢Lock同步的方式

  • 相关阅读:
    All in One 你想知道的 hacker 技术都在这里
    5 个 Git 工作流,改善你的开发流程
    完全基于 Java 的开源深度学习平台,亚马逊的大佬带你上手
    感谢 Vue.js 拯救我这个前端渣渣,让 PowerJob 有了管理后台界面
    linux报错Loading mirror speeds from cached hostfile解决方法
    Linux使用mailx通过第三方SMTP发送邮件,带附件操作
    打包发送邮件
    springboot项目中使用设计模式一策略模式
    Spring Boot 开发 WebService 服务
    常见限流算法介绍(漏桶算法、令牌桶算法)及实现--待整理
  • 原文地址:https://www.cnblogs.com/haibiscuit/p/11098072.html
Copyright © 2020-2023  润新知