当前位置: 首页 > 知识库问答 >
问题:

线程#join()是否允许其他线程通过同步块?

易招
2023-03-14

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

线程1:

synchronized(someLock)
{
    wait();
}

线程2:

synchronized(someLock)
{
    notify();
}

线程 2 能够唤醒线程 1 的事实意味着线程 2 进入了同步块,即使其他某个线程位于同一对象的同步块中也是如此。这对我来说很好,但我想知道这是否只发生在对象#wait()或所有会使线程“等待”的方法(线程#睡眠,线程#加入)上。在我的情况下,我关心线程#加入,因为如果行为与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);
    }
}

那么,多个线程是否可能因为join调用将线程置于等待状态而进入这个同步块?

共有1个答案

东门俊民
2023-03-14

首先,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.");
}

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

唤醒的线程将无法继续,直到当前线程放弃对此对象的锁定。

因此,只有在线程2退出同步块后,线程1才会在etc()之后继续执行代码。

Thread.join() 是语法糖,一种在引擎盖下使用相同的等待通知/通知All()方法的帮助器方法。事实上,javadoc 警告不要在线程对象上使用等待通知,不要干扰此机制。

此实现使用以this.isAlive.为条件的this.wait调用循环。当线程终止时,将调用this.notifyAll方法。建议应用程序不要在线程实例上使用等待、通知或通知。

Thread.sleep()等待通知无关,它不需要对象的锁,也不需要在同步的块中。

您的代码似乎正在一个名为 joinLock对象上同步,而输出线程.join() 将同步并等待输出线程对象。它们是无关的。如果出现任何问题,则如果输出线程在 joinLock 上同步,则可能会面临死锁的风险。没有输出线程的代码,我不能说。

 类似资料:
  • 下面的代码创建了一个新的custom um < code > Thread ,并等待线程结束,直到主线程再次激活。 > < li >我不太明白它是如何工作的。为什么< code > myth read . wait();立即接到电话? < li> 为什么不改用< code>Thread.join()? 公共静态void main(String[] args) {

  • 所以我有一个代码: 所以我将线程添加到我的线程列表中,然后启动这些线程。这是MyThread类: 我想做一个程序来创建线程,将它们添加到列表中,调用它们,但是每个线程都应该等到前一个线程结束它的任务。因此输出应该如下所示: 如何使用实现这一点?我尝试了使用的不同方法,但失败了。

  • 互斥锁 条件变量 POSIX信号量

  • 问题内容: 我知道在Go中,会将goroutine绑定到一个OS线程,并且不允许其他goroutine在该线程中执行。儿童goroutine也是这样吗? 例如: 这两个goroutine是在单个和排他的OS线程中执行还是仅在第一个线程中执行? 问题答案: 文档的说: LockOSThread 将调用goroutine连接 到其当前的操作系统线程。在调用goroutine退出或调用UnlockOST

  • 你好,我是多线程编程的新手。我正在尝试创建一个代码来创建一个线程THREAD1,在它完成某些事情后,它会触发另外两个线程,例如THREAD2和THREAD3,然后退出。 我写了两个可能的解决方案。 1) 使用条件变量(不起作用:在某些情况下会出现死锁): 2) THREAD1直接创建另外两个线程。 我想知道你的意见。非常感谢你

  • 线程可以等待,直到其他线程释放访问同步块的锁。我想知道当其他线程访问同步块时,一个线程可以等待多长时间?什么时候它会知道另一个线程释放了锁?