gpt4 book ai didi

java - Thread#join() 是否让其他线程通过同步块(synchronized block)?

转载 作者:行者123 更新时间:2023-12-02 01:37:31 26 4
gpt4 key购买 nike

Object#wait() 方法有一个有趣的属性,它将允许其他线程在它被阻塞时进入它的同步块(synchronized block)。示例(假设线程 1 首先运行):

主题 1:

synchronized(someLock)
{
wait();
}

主题 2:

synchronized(someLock)
{
notify();
}

线程 2 能够唤醒线程 1 的事实意味着线程 2 进入了同步块(synchronized block),即使其他线程位于同一对象的同步块(synchronized block)中。这对我来说没问题,但我想知道这种情况是否只发生在 Object#wait() 或所有会使线程“等待”的方法(Thread#sleep, Thread#join)。就我而言,我关心 Thread#join 因为如果行为与 Object#wait() 相同,它会破坏我的代码:

private void waitForClose()
{
try
{
// if one thread is waiting in join the other will wait on the semaphore
synchronized(joinLock)
{
if(outputThread != null && Thread.currentThread() != outputThread)
outputThread.join();
outputThread = null;

if(inputThread != null && Thread.currentThread() != inputThread)
inputThread.join();
inputThread = null;
}
}
catch(InterruptedException ex)
{
logger.error("Interrupted Exception while waiting for thread to join in " + name, ex);
}
}

那么是否有可能多个线程进入这个同步块(synchronized block)是因为 join 调用使线程处于等待状态?

最佳答案

首先,waitnotify 机制并不是那么有趣。它是 Java 中协调两个或多个线程的最基本方法。了解这里发生的事情很重要:

主题 1:

synchronized (someLock) {
System.out.println("Thread 1 going to wait ...");
someLock.wait();
System.out.println("Threads 1 got notified.");
}

主题 2:

synchronized (someLock) {
System.out.println("Notifying");
someLock.notify();
System.out.println("Exiting block.");
}

wait() 调用将放弃锁,允许另一个线程持有它。此时,线程 1 将无法继续即使收到通知。该文档清楚地说明了这一点:

The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.

因此,只有在线程 2 退出 synchronized block 之后,线程 1 才会继续执行 wait() 之后的代码。

Thread.join() 是语法糖,是一种在幕后使用相同的 waitnotify/notifyAll() 方法。事实上javadoc警告不要在 Thread 对象上使用 waitnotify,以免干扰此机制。

This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

Thread.sleep()waitnotify 无关。它不需要对象的锁,也不需要位于同步 block 中。

您的代码似乎在名为 joinLock 的对象上同步,而 outputThread.join() 将在 outputThread 上同步并等待目的。他们是不相关的。如果 outputThreadjoinLock 上同步,您可能会面临死锁的风险。如果没有 outputThread 的代码,我无法说。

关于java - Thread#join() 是否让其他线程通过同步块(synchronized block)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55012488/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com