Condition

作者: topshi | 来源:发表于2019-05-06 11:05 被阅读0次

重入锁的好搭档:Condition条件

线程交互中,我们介绍了线程之间的交互,主要通过两个函数完成,Object.wait()Object.notify(),这两个函数搭配synchronized关键字使用。而Condition有着大致相同的功能,它与重入锁相关联,因此Condition一般都是作为Lock的内部实现。。通过Lock接口的Condition newCondition()方法生成一个和重入锁关联的Condition实例。利用Condition对象,可以让线程在合适的时间等待,或在某一时刻得到通知继续执行。

图片来自 (J.U.C之Condition) http://cmsblogs.com/?p=2222

Condition接口提供的基本方法:

public interface Condition {
    void await() throws InterruptedException;
    void awaitUninterruptibly();
    long awaitNanos(long var1) throws InterruptedException;
    boolean await(long var1, TimeUnit var3) throws InterruptedException;
    boolean awaitUntil(Date var1) throws InterruptedException;
    void signal();
    void signalAll();
}
  • await()方法会使线程等待,同时释放当前锁,当前线程加入Condition对象维护的等待队列中,当其他线程中使用signal()signalAll()方法时,线程会重新获得锁继续执行。或当线程被中断时,也会跳出等待。
  • awaitUninterruptibly()方法与await()方法基本相同,但它不会在等待过程中响应中断。
  • signal()方法用于唤醒一个在等待中的线程。signalAll()方法会唤醒所有在等待的线程。

Condition示例

package reenterLock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
 * @Time : 2019/05/06 上午 09:58
 * @Author : xiuc_shi
 **/
public class ReenterLockCondition implements Runnable {
    public static ReentrantLock lock = new ReentrantLock();
    public static Condition condition = lock.newCondition();
    @Override
    public void run() {
        lock.lock();
        try {
            condition.await();
            System.out.println("线程继续执行");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        ReenterLockCondition tl = new ReenterLockCondition();
        Thread t1 = new Thread(tl);
        t1.start();
        Thread.sleep(2000);
        lock.lock();
        condition.signal();
        lock.unlock();
    }
}

子线程获得锁后,通过一个与重入锁lock相关联的Condition对象执行await()方法,从而释放锁;主线程获得该重入锁,然后执行signal()方法通知子线程可以继续执行,最后释放锁以让子线程获取。
Object.wait()Object.notify()一样,当线程执行condition.await()方法,线程必须已经获得了该重入锁(否则都不占用锁,哪来的释放锁让别的线程占用);同样,线程在执行condition.signal()时,系统会在等待队列中唤醒一个线程,线程一旦唤醒,它会重新尝试获得与之相关联的锁,一旦成功则继续执行。因此,执行signal()方法后需要释放锁。

相关文章

网友评论

      本文标题:Condition

      本文链接:https://www.haomeiwen.com/subject/umwloqtx.html