(Java 高并发程序设计) 一篇文章带你深入了解重入锁的好搭档:Condition

已经学习了:

如果大家理解了Object.wait()方法和Object.notify()方法,就能很容易地理解Condition对象了。它与wait()方法和notify()方法的作用是大致相同的。但是wait()方法和notify()方法是与synchronized关键字合作使用的,而Condition是与重入锁相关联的。通过lock接口(重入锁就实现了这一接口)的ConditionnewCondition()方法可以生成一个与当前重入锁绑定的Condition实例。利用Condition对象,我们就可以让线程在合适的时间等待,或者在某一个特定的时刻得到通知,继续执行。Condition接口提供的基本方法如下:

在这里插入图片描述
以上方法的含义如下:

  • await()方法会使当前线程等待,同时释放当前锁,当其他线程中使用signal()方法或者signalAll()方法时,线程会重新获得锁并继续执行。或者当线程被中断时,也能跳出等待。这和Object.wait()方法相似。
  • awaitUninterruptibly()方法与await()方法基本相同,但是它并不会在等待过程中响应中断。
  • singal()方法用于唤醒一个在等待中的线程,singalAll()方法会唤醒所有在等待中的线程。这和Obejct.notify()方法很类似。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ReenterLockCondition implements Runnable {
    public static ReentrantLock lock = new ReentrantLock();
    //通过 lock 生成一个与之绑定的 Condition 对象
    public static Condition condition = lock.newCondition();

    @Override
    public void run() {
        try {
            lock.lock();
            //要求线程在 Condition 对象上进行等待
            condition.await();
            System.out.println("Thread is going on");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReenterLockCondition r1 = new ReenterLockCondition();
        Thread t1 = new Thread(r1, "线程 r1");
        t1.start();
        System.out.println(Thread.currentThread().getName());
        Thread.sleep(2000);
        lock.lock();
        //主线程main发出通知,告知等待在Condition上的线程继续可以执行
        condition.signal();
        System.out.println(Thread.currentThread().getName());
        lock.unlock();
    }
}

Object.wait()方法和notify()方法一样,当线程使用Condition.await()方法时,要求线程持有相关的重入锁,在Condition.await()方法调用后,这个线程会释放这把锁。同理,在Condition.signal()方法调用时,也要求线程先获得相关的锁。在signal()方法调用后,系统会从当前Condition对象的等待队列中唤醒一个线程。一旦线程被唤醒,它会重新尝试获得与之绑定的重入锁,一旦成功获取,就可以继续执行了。因此,在signal()方法调用之后,一般需要释放相关的锁,让给被唤醒的线程,让它可以继续执行。比如,在本例中,第31行代码就释放了重入锁,如果省略第31行,那么,虽然已经唤醒了线程t1,但是由于它无法重新获得锁,因而也就无法真正的继续执行。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值