博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程系列---“JUC锁”03之 Condition
阅读量:4682 次
发布时间:2019-06-09

本文共 3873 字,大约阅读时间需要 12 分钟。

转自:http://www.cnblogs.com/skywang12345/p/3496716.html (含部分修改)

概要

前面对JUC包中的锁的原理进行了介绍,本章会JUC中对与锁经常配合使用的Condition进行介绍,内容包括:

Condition介绍
Condition函数列表
Condition示例

Condition介绍

Condition的作用是对锁进行更精确的控制。Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。不同的是,Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的。

 

Condition函数列表

// 造成当前线程在接到信号或被中断之前一直处于等待状态。void await()// 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。boolean await(long time, TimeUnit unit)// 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。long awaitNanos(long nanosTimeout)// 造成当前线程在接到信号之前一直处于等待状态。void awaitUninterruptibly()// 造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。boolean awaitUntil(Date deadline)// 唤醒一个等待线程。void signal()// 唤醒所有等待线程。void signalAll()

 

Condition示例

示例1是通过Object的wait(), notify()来演示线程的休眠/唤醒功能。

示例2是通过Condition的await(), signal()来演示线程的休眠/唤醒功能。

示例1

public class WaitTest1 {    public static void main(String[] args) {        ThreadA ta = new ThreadA("ta");        synchronized(ta) { // 通过synchronized(ta)获取“对象ta的同步锁”,(是当前线程,即main获取了锁ta)            try {                System.out.println(Thread.currentThread().getName()+" start ta");                ta.start();                System.out.println(Thread.currentThread().getName()+" block");                ta.wait();    // 等待                System.out.println(Thread.currentThread().getName()+" continue");            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    static class ThreadA extends Thread{        public ThreadA(String name) {            super(name);        }        public void run() {            synchronized (this) { // 通过synchronized(this)获取“当前对象的同步锁”                System.out.println(Thread.currentThread().getName()+" wakup others");                notify();    // 唤醒“当前对象上的等待线程”            }        }    }}

 

示例2

import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.ReentrantLock;public class ConditionTest1 {            private static Lock lock = new ReentrantLock();    private static Condition condition = lock.newCondition();    public static void main(String[] args) {        ThreadA ta = new ThreadA("ta");        lock.lock(); // 获取锁        try {            System.out.println(Thread.currentThread().getName()+" start ta");            ta.start();            System.out.println(Thread.currentThread().getName()+" block");            condition.await();    // 等待            System.out.println(Thread.currentThread().getName()+" continue");        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();    // 释放锁        }    }    static class ThreadA extends Thread{        public ThreadA(String name) {            super(name);        }        public void run() {            lock.lock();    // 获取锁            try {                System.out.println(Thread.currentThread().getName()+" wakup others");                condition.signal();    // 唤醒“condition所在锁上的其它线程”            } finally {                lock.unlock();    // 释放锁            }        }    }}

运行结果:(上面两个例子的运行结果都是这个)

main start tamain blockta wakup othersmain continue

通过“示例1”和“示例2”,我们知道Condition和Object的方法有一下对应关系:

Object      Condition  休眠          wait        await唤醒个线程     notify      signal唤醒所有线程   notifyAll   signalAll

Condition除了支持上面的功能之外,它更强大的地方在于:能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition。

例如,假如多线程读/写同一个缓冲区:当向缓冲区中写入数据之后,唤醒"读线程";当从缓冲区读出数据之后,唤醒"写线程";并且当缓冲区满的时候,"写线程"需要等待;当缓冲区为空时,"读线程"需要等待。         如果采用Object类中的wait(), notify(), notifyAll()实现该缓冲区,当向缓冲区写入数据之后需要唤醒"读线程"时,不可能通过notify()或notifyAll()明确的指定唤醒"读线程",而只能通过notifyAll唤醒所有线程(但是notifyAll无法区分唤醒的线程是读线程,还是写线程)。  但是,通过Condition,就能明确的指定唤醒读线程。

//TODO

后面会补充Condition结合消费者生产者模式例子。

转载于:https://www.cnblogs.com/Hermioner/p/9932160.html

你可能感兴趣的文章
CL.exe的 /D 选项, Preprocessor Macro预处理器宏定义
查看>>
[Pytorch]Pytorch中tensor常用语法
查看>>
ZOJ 1008 Gnome Tetravex
查看>>
android从内部存储写入、安装apk提示解析包错误,或者提示Permission Denied,文件不可用解决办法...
查看>>
Jenkin远程部署Tomcat8.5总结
查看>>
js复制对象
查看>>
编写Linux中sh文件执行时出现莫名字符的问题
查看>>
数据库自定义函数
查看>>
Object.assign()是浅拷贝
查看>>
简单FTP服务器搭建
查看>>
关于Sublime Text 3搭建Java环境的补充
查看>>
【FFMPEG】Ubuntu上安装FFMPEG
查看>>
【QT开发】信号转发器QSignalMapper的使用
查看>>
关于VS2010工程各种路径注意事项汇总
查看>>
Codeforces 732F. Tourist Reform (Tarjan缩点)
查看>>
JavaScript设计模式
查看>>
C++程序设计之提高效率
查看>>
set unused的用法(ORACLE删除字段)
查看>>
决策树算法
查看>>
hdu 1198 Farm Irrigation
查看>>