请参阅下面的代码。这是Oracle教程页面中经过修改的代码示例:
public class BadThreads {
static String message;
private static class CorrectorThread extends Thread {
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {}
message = "Mares do eat oats.";
System.out.println("1: "+ message);
}
}
public static void main(String args[]) throws InterruptedException {
CorrectorThread c=new CorrectorThread();
c.start();
System.out.println("0: "+ message);
c.run();
System.out.println("2: "+ message);
message = "Mares do not eat oats.";
System.out.println("3: "+ message);
Thread.sleep(2000);
System.out.println("4: "+ message);
}
}
打印
0: null
1: Mares do eat oats.
1: Mares do eat oats.
2: Mares do eat oats.
3: Mares do not eat oats.
4: Mares do not eat oats.
并且很好。
当我发表评论时
c.run();
在主要方法中,我得到了
0: null
2: null
3: Mares do not eat oats.
1: Mares do eat oats.
4: Mares do eat oats.
c 之前如何执行主?线程 c 具有与其“父”线程主相同的优先级。
c 是否可以看到主要,因此 c 正在等待主返回?这没有意义,但是我能想到的唯一的事情。
// ============================
编辑: 替换
c.run();
带
c.join();
相同的效果和更精细的编程。
答案 0 :(得分:4)
线程的全部意义在于它们并行执行。因此主线程与校正器线程并行执行。并且由于纠正器线程做的第一件事就是休眠1秒钟,主线程有足够的时间在纠正器线程更改消息之前执行其指令。
答案 1 :(得分:1)
当您调用c.run()
时,它会执行运行功能并等待完成。等待也将平行线程时间,你会看到第一种情况下的两个连续输出。在第二种情况下,线程启动并且main运行与run函数并行,因为run处于sleep状态,并且它覆盖了主要的show语句。
c.start()
启动线程与main并行运行。 c.run()
,调用run函数,并在完成时移动到下一个语句。
答案 2 :(得分:1)
这在这里没什么奇怪的,因为主线程没有任何保证,因为调用线程/方法的顺序是第一个或第二个。
首先c.start()
开始一个新线程,这意味着main继续其工作。所以在第一种情况下,你有类似的东西
0000->thread main starts the bad thread | bad thread sleeps for 1 second
and prints the message value(null)
0001->thread main runs the run() method | bad thread still is sleeping
with its thread
0002-> both thread are sleeping ....
0003->.....
1000->either bad thread or main thread changes the message value to "Mares do eat oats." (not sure which goes first!)
1001->thread main prints("1:" +message) | bad thread prints("1:" +message)
1002->thread main prints("1:" +message) | bad thread has terminated X
1003->thread main changes the message value to "Mares do not eat oats."
1004->main threads prints the message again and sleeps for 2 seconds
2004->main thread prints the message again.
而在第二种情况下,主线程没有调用run()
,因此主线程不像坏线程一样休眠1秒,只是尝试打印消息并将值更改为“妈妈不吃燕麦。“并再次打印,然后睡2秒钟,然后在1秒后坏线程被唤醒时(当主线程处于睡眠状态时),它会改变消息的值并打印出来,主线程在2秒后打印出来错误线程改变的消息。
答案在这里,由于执行顺序,不保证哪个线程首先或第二个。 this tutorial可能会帮助你。
答案 3 :(得分:0)
参见内联评论
CorrectorThread c=new CorrectorThread();
c.start(); // new thread started, but up to scheduler to decide when to give it a slice of time
System.out.println("0: "+ message);
c.run(); // ran in main thread
System.out.println("2: "+ message); // as expected, message was set by the other thread
message = "Mares do not eat oats.";
System.out.println("3: "+ message); // as expected
Thread.sleep(2000);
System.out.println("4: "+ message); // as expected
c.start()
和c.run()
将最终调用CorrectorThread#run()
但在不同的主题中。这取决于Thread
调度程序,它将首先到达那里。
在您不调用c.run()
的示例中,调度程序有时间调用
System.out.println("0: "+ message); // null
System.out.println("2: "+ message); // null
在其他线程有时间初始化message
之前。
答案 4 :(得分:0)
试试这样: -
public class BadThreads {
static String message;
private static class CorrectorThread extends Thread {
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {}
message = "Mares do eat oats.";
System.out.println("3: "+ message);
}
}
public static void main(String args[]) throws InterruptedException {
CorrectorThread c=new CorrectorThread();
c.start();
System.out.println("0: "+ message);
System.out.println("1: "+ message);
message = "Mares do not eat oats.";
System.out.println("2: "+ message);
Thread.sleep(2000);
System.out.println("4: "+ message);
}
}