我的代码
public class Main {
public static void main(String[] args)throws Exception {
Thread thread1=new Thread(new Runnable()
{
public void run()
{
System.out.println("Thread1");
}
});
thread1.join();
thread1.start();
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
}
}
有时“Thread1”会在所有数字打印之前打印出来。有什么理由吗? Thread1不应该等到主线程完成吗?
答案 0 :(得分:4)
thread1.join();
thread1.start()
制作
thread1.start()
thread1.join();
它将通过thread1.start()
从主线程启动一个线程,主线程将继续在下一行执行,它将看到thread1.join();
,它将暂停主线程的执行,直到thread1完成。所以你的工作将完成
答案 1 :(得分:1)
通过调用Thread.join()
当前线程等待您调用的线程join()
。
在你的情况下,你等待thread1
在它开始之前完成。
如果您希望thread1
等待数字完成打印,可以使用CountDownLatch
docs:
public class Main {
public static final CountDownLatch startSignal = new CountDownLatch(1);
public static void main(String[] args)throws Exception {
Thread thread1=new Thread(new Runnable()
{
public void run()
{
try {
startSignal.await();
System.out.println("Thread1");
} catch (InterruptedException ex) {}
}
});
thread1.start();
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
startSignal.countDown();
thread1.join();
}
}
答案 2 :(得分:1)
尽管您应该在thread1.start()
之前调用thread1.join()
,但实际上您不知道线程何时会被执行。打印i
时可能会发生这种情况,可能会发生之前或之后发生。取决于您的操作系统的线程调度机制。您的正确代码应如下所示:
public class Main {
public static void main(String[] args)throws Exception {
Thread thread1=new Thread(new Runnable()
{
public void run()
{
System.out.println("Thread1");
}
});
// start the thread
thread1.start();
// print the numbers... meanwhile your thread *could* get executed
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
// wait for thread1 to finish
thread1.join();
}
}
答案 3 :(得分:1)
实际上,在调用join()之前,我们应该确保系统已根据我们的“.start()”请求(在start()返回之前不一定发生)启动线程,如join()并没有真正等到一个线程死掉,相反,它只是在线程没有运行时立即返回。这可以在线程启动之前或完成之后发生。请参阅Allen Holub的“驯服Java线程”,第87页。以下是我认为编写此代码的正确方法:
import java.util.concurrent.Semaphore;
public class Main {
public static void main(String[] args)throws Exception {
final Semaphore waitForThreadToStart = new Semaphore (0);
Thread thread1=new Thread(new Runnable()
{
public void run()
{
waitForThreadToStart.release();
System.out.println("Thread1");
}
});
thread1.start();
waitForThreadToStart.acquire(); // Wait for thread to start
thread1.join(); // Now do the join.
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}