Java 多线程编程:为什么只有林一线程执行?
在使用 ReentrantLock 锁时,如果观察到只有第一个线程在执行,而第二个线程似乎被阻塞,这可能是由于锁机制的特性导致的。
ReentrantLock 锁能够保证同一时刻只有一个线程进入临界区,但并不能保证两个线程交替执行。当第一个线程释放锁后,第二个线程还需要竞争锁才能进入临界区执行。如果第二个线程没有竞争到锁,就会一直等待,导致只有一个线程在执行。
这可能是由于第一个线程先启动并且运行速度较快,导致第二个线程竞争锁失败。
为了实现更精细的线程控制,可以使用 Condition 对象。Condition 对象可以用来创建多个等待队列,让不同的线程在不同的条件下等待,从而实现线程的轮流执行。
示例代码:
public class test02 {
public static void main(String[] args) {
water water = new water();
new Thread(() -> {
for (int i = 0; i < 40; i++) {
water.drink();
}
}, '林一').start();
new Thread(() -> {
for (int i = 0; i < 40; i++) {
water.drink();
}
}, '林二').start();
}
}
class water {
private Integer num = 40;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean is林一 = true;
public void drink() {
lock.lock();
try {
if (num > 0) {
if (is林一) {
System.out.println(Thread.currentThread().getName() + '喝了第 ' + (num--) + '杯,还剩下:' + num);
is林一 = false;
condition.signalAll(); // 通知另一个线程
condition.await(); // 等待被通知
} else {
condition.await(); // 等待被通知
System.out.println(Thread.currentThread().getName() + '喝了第 ' + (num--) + '杯,还剩下:' + num);
is林一 = true;
condition.signalAll(); // 通知另一个线程
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
在上述代码中,我们使用 Condition 对象创建了两个等待队列,分别对应 林一 和 林二 两个线程。每次执行 drink() 方法后,会根据 is林一 的值来决定是通知 林一 还是 林二 线程执行。这样就可以实现两个线程轮流执行。
原文地址: https://www.cveoy.top/t/topic/ndlY 著作权归作者所有。请勿转载和采集!