Condition接口:
Condition可以通俗理解为条件队列,一个Condition的实例必须与一个Lock绑定,因此Condition一般都是作为Lock的内部实现。
它是java.util.concurrent提供的一个接口,其作用是让线程先等待,当条件允许后,再通过condition唤醒等待的线程。
- await(),造成当前线程在接受信号和被中断之后一直在等待状态。
- await(long time,TimeUnit unit),造成当前线程在接到信号,被中断或到达指定等待时间之前一直在等待状态。
- awaitNanos(long nanosTimeout),造成在当前线程在接到信号,被中断或到达指定时间之前一直在等待状态,返回值表示剩余时间,如果在nanosTimesout之前被唤醒,那么返回值=nanosTimeout-消耗时间,如果返回值<=0,则可以认定它已经超时了。
- awaitUninterruptibly(),造成当前线程在接到信号之后处于等待状态。
- awaitUntil(Date deadline),造成当前线程在接到信号,被中断或达到指定最后期限之前一直处在等待状态,如果没有到指定时间就被通知,则返回true,否则表示到了指定时间,返回false。
- signal(),唤醒一个等待线程,该线程从等待方法返回前必须获得与Condition相关的锁。
- signal()All,唤醒所有的线程,能够从等待方法返回的线程必须获得与Condition相关的锁。
condition常见例子arrayblockingqueue。下面是demo:
package thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* @author zhangliang
*
* 2016年4月8日 下午5:48:54
*/
public class ConTest {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
public static void main(String[] args) {
// TODO Auto-generated method stub
ConTest test = new ConTest();
Producer producer = test.new Producer();
Consumer consumer = test.new Consumer();
consumer.start();
producer.start();
}
class Consumer extends Thread{
@Override
public void run() {
consume();
}
private void consume() {
try {
lock.lock();
System.out.println("我在等一个新信号"+this.currentThread().getName());
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
System.out.println("拿到一个信号"+this.currentThread().getName());
lock.unlock();
}
}
}
class Producer extends Thread{
@Override
public void run() {
produce();
}
private void produce() {
try {
lock.lock();
System.out.println("我拿到锁"+this.currentThread().getName());
condition.signalAll();
System.out.println("我发出了一个信号:"+this.currentThread().getName());
} finally{
lock.unlock();
}
}
}
}
Condition的特殊点:
当调用condition.await()阻塞线程时会自动释放锁,不管调用多少次lock.lock(),这时阻塞在lock.lock()方法上线程则可以获得锁;
当调用condition.singnal()唤醒线程时会继续上次阻塞的位置继续执行,默认会自动重新获取锁。