zoukankan      html  css  js  c++  java
  • 玩转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同步的方式

  • 相关阅读:
    OpenCV IplImage FlyCapture2 Image Conversion 两种图像类的相互转化
    [FlyCapture2] Bumblebee XB3 Save Images to Three AVI Files (Left, Center and Right) 大黄蜂立体相机保存捕获的视频到左中右三个不同的文件
    Links About Point Grey FlyCapture2 and Triclops
    Android方法数methods超过65536
    Android studio 3.1.1 找不到DDMS
    Android Error:Could not run build action using Gradle installation
    Android Studio maven-metadata.xml 卡着不动原因和解决方法
    Android 4.4及以后将内容布局延伸到状态栏
    java 通过文件后缀名查找文件
    GreenDao 数据库升级 连接多个DB文件 或者指定不同的model&dao目录
  • 原文地址:https://www.cnblogs.com/haibiscuit/p/11098072.html
Copyright © 2011-2022 走看看