Java中的锁(三)

it2026-09-26  12

文章目录

Java中的锁(三)使用ConditionCondition中的方法注意事项实现等待通知机制

Java中的锁(三)

使用Condition

Condition和Lock结合使用 = wait/notify和synchronized结合使用

Condition中的方法

void await() = waitvoid await(long nanos) 有超时时间 = wait(long timeout)void signal = notify 唤醒一个void signalAll() = notifyAll 唤醒所有

注意事项

和wait、notify一样,在执行await、signal、signalAll的前提也必须获得lock锁才可以执行

实现等待通知机制

import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import lombok.SneakyThrows; import org.junit.Test; /** * Lock结合Condition实现等待通知,记得释放锁。所有等待、通知机制在lock和unlock之间 * * Lock lock = new ReentrantLock(); * Condition condition = lock.newCondition(); * lock.lock;/lock.tryLock();/lock.tryLock(long nanos) * try{ * condition.await();/condition.await(long nanos);/condition.signal();/condition.signalAll(); * } finally { * lock.unlock(); * } * * @author jacksparrow414 * @date 2020/10/21 */ public final class ThreadLockConditionTest { // 可重入锁,默认是非公平锁 static Lock lock = new ReentrantLock(); static Condition condition = lock.newCondition(); static boolean flag = true; @Test @SneakyThrows public void assertLockCondition() { Thread threadN = new Thread(new ThreadLockConditionTest.threadN(), "threadN"); Thread threadM = new Thread(new ThreadLockConditionTest.threadM(), "threadM"); threadN.start(); TimeUnit.SECONDS.sleep(1); threadM.start(); TimeUnit.SECONDS.sleep(10); } static class threadN implements Runnable { @Override public void run() { // 不要将获取锁的过程写在try块中,因为如果在获取锁(自定义锁的实现)时发生了异常, //异常抛出的同时,也会导致锁无故释放。 lock.lock(); while (flag) { System.out.println(Thread.currentThread().getName() + " flag is true wait"); try { condition.await(); } catch (InterruptedException exception) { exception.printStackTrace(); } finally { // 可重入锁要记得手动释放锁 lock.unlock(); } System.out.println(Thread.currentThread().getName() + "falg is false running"); } } } static class threadM implements Runnable { @Override public void run() { lock.lock(); System.out.println(Thread.currentThread().getName() + " acquire lock"); flag = false; // 唤醒所有等待的线程 try { TimeUnit.SECONDS.sleep(3); condition.signalAll(); } catch (InterruptedException exception) { exception.printStackTrace(); }finally { lock.unlock(); } // 唤醒等待线程的操作要放到同步体里,否则会报错 // condition.signalAll(); lock.lock(); System.out.println(Thread.currentThread().getName() + " acquire again"); condition.signalAll(); lock.unlock(); } } }
最新回复(0)