在使用 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林一 的值来决定是通知 林一 还是 林二 线程执行。这样就可以实现两个线程轮流执行。

Java 多线程编程:为什么只有林一线程执行?

原文地址: https://www.cveoy.top/t/topic/ndlY 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录