Java 是太阳';s Thread.join方法已断开,因为它同步了线程对象的usng?
通过运行测试程序和查看源代码,很明显,Sun实现的方法并不是简单地给指定的线程分配时间,而是首先尝试获取线程对象上的监视器。具体来说,该方法实现为“同步” 注意,wait和notify方法也需要监视器,但与join不同,调用方有责任在调用之前获取监视器,文档中明确说明了这一点。join依赖于监视器这一事实在Javadocs中没有记录,尽管进行推断可能是很自然的 文档是否足够清晰 此外,如果线程由于某种原因无法获取监视器,它将挂起,可能永远挂起。在等待监视器时,线程是不可中断的,并且不会引发文档中描述的InterruptedException。另一方面,不清楚为什么线程不能获得监视器,除非在编程错误的情况下 担心显示器上的争用是否合理 最后,让超时操作依赖于获取监视器似乎是不合适的,除非可以保证获取监视器的任务本身会超时Java 是太阳';s Thread.join方法已断开,因为它同步了线程对象的usng?,java,multithreading,join,timeout,Java,Multithreading,Join,Timeout,通过运行测试程序和查看源代码,很明显,Sun实现的方法并不是简单地给指定的线程分配时间,而是首先尝试获取线程对象上的监视器。具体来说,该方法实现为“同步” 注意,wait和notify方法也需要监视器,但与join不同,调用方有责任在调用之前获取监视器,文档中明确说明了这一点。join依赖于监视器这一事实在Javadocs中没有记录,尽管进行推断可能是很自然的 文档是否足够清晰 此外,如果线程由于某种原因无法获取监视器,它将挂起,可能永远挂起。在等待监视器时,线程是不可中断的,并且不会引发文档中
依赖于join()的监视器是合理的实现吗?甚至有可能以其他方式实现它吗?
Thread.join
调用wait
,从而释放监视器。因为这意味着“加入”线程也不会阻止任何其他线程调用加入,所以我怀疑这回答了大多数其他查询。它不会阻止另一个调用者在线程的监视器上同步(哦,公共监视器的乐趣),但这意味着普通情况下工作正常
为了证明您的第一点是错误的,下面的示例创建了10个线程,每个线程在主线程上等待5秒钟。(请忽略吞咽和滥用Date
的可怕异常。它仅用于研究线程行为。)
import java.util.*;
公开课考试
{
公共静态void main(字符串[]args)引发异常
{
对于(int i=0;i<10;i++)
{
新线程(新线程联接程序(Thread.currentThread(),i))
.start();
}
尝试
{
睡眠(10000);
}
捕获(中断异常e){}
}
私有静态类ThreadJoiner实现可运行
{
私有最终线程threadToJoin;
int-id;
公共ThreadJoiner(线程threadToJoin,int id)
{
this.threadToJoin=threadToJoin;
this.id=id;
}
公开募捐
{
尝试
{
System.out.println(“线程”+id+
“正在等待”+新日期());
螺纹连接。连接(5000);
System.out.println(“线程”+id+
“已在“+新日期()完成等待”;
}
捕获(中断异常e){}
}
}
}
如果您运行它,您将看到所有线程几乎同时开始和结束等待。如果你的担忧是有根据的,你不会得到“交错”的结果。
Thread.join
callswait
,这会释放监视器。因为这意味着“加入”线程也不会阻止任何其他线程调用加入,所以我怀疑这回答了大多数其他查询。它不会阻止另一个调用者在线程的监视器上同步(哦,公共监视器的乐趣),但这意味着普通情况下工作正常
为了证明您的第一点是错误的,下面的示例创建了10个线程,每个线程在主线程上等待5秒钟。(请忽略吞咽和滥用Date
的可怕异常。它仅用于研究线程行为。)
import java.util.*;
公开课考试
{
公共静态void main(字符串[]args)引发异常
{
对于(int i=0;i<10;i++)
{
新线程(新线程联接程序(Thread.currentThread(),i))
.start();
}
尝试
{
睡眠(10000);
}
捕获(中断异常e){}
}
私有静态类ThreadJoiner实现可运行
{
私有最终线程threadToJoin;
int-id;
公共ThreadJoiner(线程threadToJoin,int id)
{
this.threadToJoin=threadToJoin;
this.id=id;
}
公开募捐
{
尝试
{
System.out.println(“线程”+id+
“正在等待”+新日期());
螺纹连接。连接(5000);
System.out.println(“线程”+id+
“已在“+新日期()完成等待”;
}
捕获(中断异常e){}
}
}
}
如果您运行它,您将看到所有线程几乎同时开始和结束等待。如果你的担忧是有根据的,你不会像你那样“错开”结局
很明显,Sun实现的方法并不是简单地给指定的线程分配时间,而是首先尝试获取线程对象上的监视器
它不会屈服于所连接的线程,它只是等待,并假设在某个时刻线程将运行到完成。在线程上使用join()不会使它比任何其他准备运行的线程更有可能运行
import java.util.*;
public class Test
{
public static void main(String[] args) throws Exception
{
for (int i=0; i < 10; i++)
{
new Thread(new ThreadJoiner(Thread.currentThread(), i))
.start();
}
try
{
Thread.sleep(10000);
}
catch (InterruptedException e) {}
}
private static class ThreadJoiner implements Runnable
{
private final Thread threadToJoin;
int id;
public ThreadJoiner(Thread threadToJoin, int id)
{
this.threadToJoin = threadToJoin;
this.id = id;
}
public void run()
{
try
{
System.out.println("Thread " + id +
" waiting at " + new Date());
threadToJoin.join(5000);
System.out.println("Thread " + id +
" finished waiting at " + new Date());
}
catch (InterruptedException e) {}
}
}
}