java Thread.join不';I don’我没有按预期工作

java Thread.join不';I don’我没有按预期工作,java,multithreading,Java,Multithreading,我有以下课程 类ThreadDemo扩展线程{ 私有线程t; 私有字符串threadName; ThreadDemo(字符串名称){ threadName=名称; } 公开募捐{ 对于(int i=5;i>0;i--){ System.out.println(“线程”+threadName+“计数器”--“+i”); } 试一试{ 睡眠(1000); }捕获(例外e){ System.out.println(“睡眠问题”); } System.out.println(“完成运行”); 试一试{

我有以下课程

类ThreadDemo扩展线程{
私有线程t;
私有字符串threadName;
ThreadDemo(字符串名称){
threadName=名称;
}
公开募捐{
对于(int i=5;i>0;i--){
System.out.println(“线程”+threadName+“计数器”--“+i”);
}
试一试{
睡眠(1000);
}捕获(例外e){
System.out.println(“睡眠问题”);
}
System.out.println(“完成运行”);
试一试{
睡眠(1000);
}捕获(例外e){
System.out.println(“睡眠问题”);
}
}
公共无效开始(){
t=新线程(此,线程名称);
t、 开始();
}
}
测试结果如下所示

公共类主{
公共静态void main(字符串[]args){
ThreadDemo T1=新的ThreadDemo(“线程-1”);
ThreadDemo T2=新的ThreadDemo(“线程-2”);
T1.start();
T2.start();
//让我们给线程一些运行时间
试一试{
睡眠(10);
}捕获(例外e){
System.out.println(“主要睡眠问题”);
}
试一试{
T1.join();
T2.连接();
}捕获(例外e){
系统输出打印项次(“中断”);
}
System.out.println(“精加工主管道”);
}
}

尽管我使用T1.join()和T2.join()等待它们完成,为什么我总是在输出中的“Finishing run”之前获取“Finishing main”?起初我认为这可能是由于缓冲区延迟,所以我在run()的末尾添加了Thread.sleep(1000)以留出一些时间打印“Finishing run”,但这没有帮助。我猜这是由于线程的首次出现。sleep(1000)(当我移除它时,它工作正常),但不知道为什么。

这是因为:

public void start () {
    t = new Thread (this, threadName);
    t.start ();
}
因此,您的
ThreadDemo
实例实际上从未作为线程启动:正在打印
Finishing run
消息的线程就是在该方法中创建的线程。该线程与
ThreadDemo
之间没有链接

删除
start()
方法。

这是因为:

public void start () {
    t = new Thread (this, threadName);
    t.start ();
}
因此,您的
ThreadDemo
实例实际上从未作为线程启动:正在打印
Finishing run
消息的线程就是在该方法中创建的线程。该线程与
ThreadDemo
之间没有链接


删除
start()
方法。

您的
ThreadDemo
类扩展线程;不要定义自己的
start
方法,而是使用类附带的supemethod。“当我删除它时,它工作得很好”不,它只是因为
线程,线程执行得比主线程快。睡眠(10)
。这只是侥幸。
扩展线程
是您的第一个问题。在描述任务时,您应该首选
实现Runnable
,然后将该任务传递给应该处理它的工作者(线程)。@Pshemo或者根本不将其传递给线程,而是将其传递给
ExecutorService
或类似的为您管理线程的人。您的
ThreadDemo
类扩展了线程;不要定义自己的
start
方法,而是使用类附带的supemethod。“当我删除它时,它工作得很好”不,它只是因为
线程,线程执行得比主线程快。睡眠(10)
。这只是侥幸。
扩展线程
是您的第一个问题。在描述任务时,您应该更喜欢
实现可运行的
,然后将该任务传递给应该处理它的工作线程。@Pshemo或者根本不传递给线程,而是传递给
ExecutorService
或类似的为您管理线程的方法。是的,在重写标准方法之前请三思是的,在重写标准方法(这里是方法“start()”)之前要三思。