Java 为什么ReentrantLock可以';我拿不到锁

Java 为什么ReentrantLock可以';我拿不到锁,java,multithreading,Java,Multithreading,我有一个测试条件的简单程序,如下所示: public class ThreadTest2 { Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); public void conditionWait() throws InterruptedException { lock.lock(); try { System.ou

我有一个测试条件的简单程序,如下所示:

public class ThreadTest2 {
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public void conditionWait() throws InterruptedException {
        lock.lock();
        try {
            System.out.println("1");
            condition.await();
            System.out.println("2");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void conditionSignal() throws InterruptedException {
        lock.lock();
        try {
            System.out.println("3");
            condition.signal();
            System.out.println("4");
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest2 test = new ThreadTest2();

        test.conditionWait();

        Thread.sleep(2000);

        test.conditionSignal();
    }
}
结果是:一,, 似乎conditionWait()方法已经获取了锁,因此conditionSignal()方法无法获取它。但是,如果我将程序更改为在每个方法中使用线程,如下所示:

public class ThreadTest2 {
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public void conditionWait() throws InterruptedException {
        new Thread() {
            public void run() {
                lock.lock();
                try {
                    System.out.println("1");
                    condition.await();
                    System.out.println("2");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            };
        }.start();
    }

    public void conditionSignal() throws InterruptedException{
        new Thread() {
            public void run() {
                lock.lock();
                try {
                    System.out.println("3");
                    condition.signal();
                    System.out.println("4");
                } finally {
                    lock.unlock();
                }
            };
        }.start();
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest2 test = new ThreadTest2();

        test.conditionWait();

        Thread.sleep(2000);

        test.conditionSignal();
    }
}

结果是:1 3 4 2,那么它们之间的区别是什么,为什么使用线程可以获得锁,而在
conditionWait
中没有线程就不能,您获取锁并等待该条件。这确实会暂时释放锁,但它仍可能永远等待


等待
完成的唯一方法是发出信号通知条件。如果你在等待,信号从哪里来?仅来自另一个线程。但是没有其他线程
,因此这将永远等待。

因为锁和条件是为在线程之间工作而设计的。在第一次测试中,只有一个线程。这是怎么回事?嗯,我还是不明白为什么要锁。锁();可以用于不同的线程,在第二次测试中,它可以获得锁,但在第一次测试中,它无法在第二次测试中,conditionWait()中的线程执行lock.lock以获得锁,并且在等待时不释放锁,为什么conditionSignal()中的线程可以再次执行lock.lock以获取lock@gesanri-在第一次测试中,代码永远不会超过
条件。wait()
so
condition.signal()
永远不会被调用,因为它是在
conditionSignal()
中调用的,而一个线程无法到达那里,因为它正在等待条件。@gesanri-在第二个测试中
conditionWait()
获取锁并等待信号。同时,在另一个线程中,调用
conditionSignal()
释放
wait
。请注意,
condition.await()
在等待之前释放锁,以便其他线程可以在发出信号之前获取锁。