【高并发系列】10、重入锁搭档 - Condition

java.util.concurrent.locks.Lock接口方法如下:

void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();

java.util.concurrent.locks.Condition接口方法如下:

void await() throws InterruptedException;
void awaitUninterruptibly();
long awaitNanos(long nanosTimeout) throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;
boolean awaitUntil(Date deadline) throws InterruptedException;
void signal();
void signalAll();
  • await()方法会使当前线程等待,同时释放当前锁,当其他线程中使用signal()方法或signalAll()方法时,线程会重新获得锁并继续执行;或者当线程被中断时,也能跳出等待;这和Object.wait()方法相似;
  • awaitUninterruptibly()方法与await()方法基本相同,但是并不会在等待过程中响应中断;
  • signal()方法用于唤醒一个在等待中的线程;
  • signalAll()方法会唤醒所有在等待中的线程;
public class ReentrantLockConditionDemo implements Runnable {
	private static ReentrantLock lock = new ReentrantLock();
	private static Condition condition = lock.newCondition();
	@Override
	public void run() {
		lock.lock();
		try {
			System.out.println("Thread is starting.");
			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 {
		ReentrantLockConditionDemo rlcd = new ReentrantLockConditionDemo();
		Thread thread = new Thread(rlcd, "Thread-condition");
		thread.start();
		TimeUnit.SECONDS.sleep(2);
		lock.lock();
		try {
			condition.signal();
		} finally {
			lock.unlock();
		}
	}
}

与Object.wait()方法和notify()方法一样,当线程使用Condition.await()方法时,要求线程持有相关的重入锁,在Condition.await()方法调用后,这个线程会释放这把锁;

同理,在signal()方法调用后,系统会从当前Condition对象的等待队列中唤醒一个线程;一旦线程被唤醒,它会重新尝试获得与之绑定的重入锁,一旦成功获取,就可以了继续执行了;

在main()方法中,如果在signal()方法后省略lock.unlock(),虽然使用signal()方法唤醒了线程,但是由于该线程无法获得锁,因此也无法真正的继续执行;

猜你喜欢

转载自blog.csdn.net/hellboy0621/article/details/87034254