JUC中的Condition对象
Object对象中的wait(),notify()方法,用于线程等待和唤醒等待中的线程,wait()方法和notify()方法必须放在同步块内调用(synchronized块内),否则会报错.
Condition 对象就是在Lock下的等待/通知机制。
Condition的功能特性与Object的不同:
- Condition能够支持阻塞不响应中断(awaitUninterruptibly()方法),而通过使用Object方式不支持
- Condition能够支持多个等待队列(new 多个Condition对象),而Object方式只能支持一个
- Condition能够支持超时时间设置到将来某个时间(date),而Object不支持
获取Conditino对象方式: reentrantLock.newCondition();
Condition常用方法
- void await() throws InterruptedException;方法会释放锁,让当前线程等待,支持唤醒,支持线程中断。
- void awaitUninterruptibly();方法会释放锁,让当前线程等待,支持唤醒,不支持线程中断
- long awaitNanos(longnanos Timeout) throws InterruptedException;参数为纳秒,此方法会释放锁,让当前线程等待,支持唤醒,支持中断。超时之后返回的,结果为负数;超时之前被唤醒返回的,结果为正数(表示返回时距离超时时间相差的纳秒数)
- void signal();会唤醒一个等待中的线程,然后被唤醒的线程会被加入同步队列,去尝试获取锁
- boolean await(longtime,TimeUnitunit) throws InterruptedException;方法会释放锁,让当前线程等待,支持唤醒,支持中断。超时之后返回的,结果为false;超时之前被唤醒返回的,结果为true
- boolea nawaitUntil(Date deadline) throws InterruptedException;参数表示超时的截止时间点,方法会释放锁,让当前线程等待,支持唤醒,支持中断。超时之后返回的,结果为false;超时之前被唤醒返回的,结果为true
- void signalAll();会唤醒所有等待中的线程,将所有等待中的线程加入同步队列,然后去尝试获取锁
案例说明
基本使用
package com.lg.conditon;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Demo1 {
static ReentrantLock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
public static class T1 extends Thread{
@Override
public void run() {
try {
System.out.println(this.getName()+"线程准备获取锁");
lock.lock();
System.out.println(this.getName()+"线程获取锁成功,准备阻塞,等待被唤醒");
condition.await();
System.out.println(this.getName()+"线程被唤醒成功,执行完业务,准备释放锁");
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
System.out.println(this.getName()+"线程释放锁成功");
}
}
}
public static class T2 extends Thread{
@Override
public void run() {
try {
System.out.println(this.getName()+"线程准备获取锁");
lock.lock();
System.out.println(this.getName()+"线程获取锁成功,进行业务处理");
TimeUnit.SECONDS.sleep(3);
System.out.println(this.getName()+"线程唤醒被阻塞的线程");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
condition.signal();
lock.unlock();
System.out.println(this.getName()+"线程释放锁");
}
}
}
public static void main(String[] args) throws InterruptedException {
T1 t1 = new T1();
t1.setName("t1");
t1.start();
TimeUnit.SECONDS.sleep(5);
T2 t2 = new T2();
t2.setName("t2");
t2.start();
}
}
阻塞超时自动返回
public class Demo2 {
static ReentrantLock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
public static class T1 extends Thread{
@Override
public void run() {
try {
System.out.println(this.getName()+"线程准备获取锁");
lock.lock();
System.out.println(this.getName()+"线程获取锁成功,处理业务");
System.out.println(this.getName()+"线程阻塞5秒自动返回");
boolean flag = condition.await(5, TimeUnit.SECONDS);
System.out.println(flag);
System.out.println(this.getName()+"线程自动唤醒成功");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
System.out.println(this.getName()+"线程释放锁成功");
}
}
}
public static void main(String[] args) {
T1 t1 = new T1();
t1.setName("t1");
t1.start();
}
}