之前文章有写wait/notify/notifyAll
Condition作用相似,可能会多一些性能 比方:反对不响应中断、可指定工夫点完结期待、可多条件(new 多个Condition)
Condition的await 与wait相似 必须在获取锁的时候能力await
一、 应用
/**
* @author 木子的昼夜
*/
public class ConditionTest {
public static Lock lock = new ReentrantLock();
//
public static Condition cd01 = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
ConditionTest test = new ConditionTest();
new Thread(test::say01).start();
Thread.sleep(5000);
new Thread(test::say02).start();
}
/**
* 说:我饿了
*/
public void say01(){
try{
lock.lock();
System.out.println("我饿了");
cd01.await();
System.out.println("吃饱了");
} catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* 说:饭好了
*/
public void say02(){
try{
lock.lock();
cd01.signal();
System.out.println("开饭了");
} catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
输入后果:
我饿了
开饭了
吃饱了
二、 不响应中断
看一下say01 say02 可中断 say03 不可中断
public class ConditionTest02 {
public static Object obj = new Object();
public static Lock lock = new ReentrantLock();
public static Condition cd01 = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
ConditionTest02 test = new ConditionTest02();
Thread thread = new Thread(test::say01);
Thread thread02 = new Thread(test::say02);
Thread thread03 = new Thread(test::say03);
thread.start();
thread02.start();
thread03.start();
// 饿他们5秒钟
Thread.sleep(5000);
// 中断
thread.interrupt();
thread02.interrupt();
// say03会中断失败
thread03.interrupt();
}
/**
* 说:小强饿了
*/
public void say01(){
try{
lock.lock();
System.out.println("小强饿了");
System.out.println("小强期待投食");
cd01.await();
System.out.println("小强吃饱了");
}catch (InterruptedException e){
System.out.println("小强进来觅食了");
}catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* 说:小明饿了
*/
public void say02(){
try{
synchronized (obj){
System.out.println("小明饿了");
System.out.println("小明期待投食");
obj.wait();
System.out.println("小明吃饱了");
}
} catch (InterruptedException e){
System.out.println("小明进来觅食了");
}
}
/**
* 说:小月鸟饿了 中断无用
*/
public void say03(){
try{
lock.lock();
System.out.println("小月鸟饿了");
System.out.println("小月鸟期待投食");
cd01.awaitUninterruptibly();
System.out.println("小月鸟吃饱了");
}catch (Exception e){
System.out.println("小月鸟进来觅食了");
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
输入后果:
小明饿了
小明期待投食
小强饿了
小强期待投食
小月鸟饿了
小月鸟期待投食
小明进来觅食了
小强进来觅食了
三、 超时进行wait
condition能够await一段时间 本人意识到 没人理他 而后就完结await了
Object的wait也能够指定超时工夫
public class ConditionTest03 {
public static Lock lock = new ReentrantLock();
//
public static Condition cd01 = lock.newCondition();
public static void main(String[] args) {
ConditionTest03 test = new ConditionTest03();
new Thread(test::say01).start();
}
/**
* 说:我饿了
*/
public void say01(){
try{
lock.lock();
System.out.println("我饿了");
System.out.println("期待投喂");
//
// 这个须要的单位是毫奥妙 也就是秒*1000*1000000 也就是5000000000L毫奥妙 = 5秒
// 也能够这样获取 nanos就等于 也就是5000000000L
long nanos = TimeUnit.SECONDS.toNanos(5);
long res = cd01.awaitNanos(5000000000L);
// 也能够这样 返回true false
// boolean res = cd01.await(10,TimeUnit.SECONDS);
// 超时
if (res <= 0){
System.out.println("没人投喂 我本人觅食去");
} else {
System.out.println("有人投喂 我吃饱了");
}
} catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
四、指定工夫
能够指定到指定某个工夫点 就完结wait
public class LockTest04 {
// 新建锁
public static Lock lock = new ReentrantLock(false);
public static Condition cd = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
try {
lock.lock();
long l = System.currentTimeMillis();
l = l +1000*10;
Date date = new Date(l);
boolean res = cd.awaitUntil(date);
if(res) {
System.out.println("被告诉");
} else {
System.out.println("没人告诉 到时见我本人走了");
}
} catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}).start();
}
}
五、 创立多个condition
这里举个例子:小强 和 小月月 两个人在玩儿玩具 小强玩会儿 不玩儿了给小月月 小月月不玩了再给小强
public class PlayTest {
public static Lock lock = new ReentrantLock();
public static Condition cd01 = lock.newCondition();
public static void main(String[] args) {
PlayTest test = new PlayTest();
new Thread(test::xiaoqiangPlay).start();
new Thread(test::xiaoxuexuePlay).start();
}
// 小强玩儿
public void xiaoqiangPlay(){
try {
while (true){
lock.lock();
System.out.println("小强玩儿");
Thread.sleep(5000);
// 告诉他人玩儿
cd01.signal();
// 本人等着他人告诉
cd01.await();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
// 下月月玩
public void xiaoxuexuePlay(){
try {
while(true){
lock.lock();
System.out.println("小月月玩儿");
Thread.sleep(5000);
// 告诉他人玩儿
cd01.signal();
// 本人等着他人告诉
cd01.await();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
能够应用两个condition
public class PlayTest02 {
public static Lock lock = new ReentrantLock();
public static Condition cd01 = lock.newCondition();
public static Condition cd02 = lock.newCondition();
public static void main(String[] args) {
PlayTest02 test = new PlayTest02();
new Thread(test::xiaoqiangPlay).start();
new Thread(test::xiaoxuexuePlay).start();
}
// 小强玩儿
public void xiaoqiangPlay(){
try {
while (true){
lock.lock();
System.out.println("小强玩儿");
Thread.sleep(5000);
// 告诉他人玩儿
cd01.signal();
// 本人等着他人告诉
cd02.await();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
// 下月月玩
public void xiaoxuexuePlay(){
try {
while(true){
lock.lock();
System.out.println("小月月玩儿");
Thread.sleep(5000);
// 告诉他人玩儿
cd02.signal();
// 本人等着他人告诉
cd01.await();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
两个condition互不烦扰,能够指定condition await / signal
condition的signalAll 与 notifyAll 相似 不再代码演示
六、总结
- 创立Condition (可创立多个 互不影响)
- 必须在lock获取锁之后能力应用
- await 反对不相应中断、超时(Object wait也反对)、指定工夫点完结
- signal只会唤醒一个线程 signalAll 会唤醒所有线程
有问题能够留言哦,可也以公众号留言(回复快):
发表回复