Java线程编程示例-程序运行异常
我正在读保罗·海德的《Java线程编程》一书。我正在读第一章。我正在EclipseIDE中运行各种示例程序Java线程编程示例-程序运行异常,java,multithreading,Java,Multithreading,我正在读保罗·海德的《Java线程编程》一书。我正在读第一章。我正在EclipseIDE中运行各种示例程序 public class TwoThreadAlive extends Thread { public void run() { for (int i = 0; i < 10; i++) { printMsg(); } } public void printMsg() { // get a reference to the thread ru
public class TwoThreadAlive extends Thread {
public void run() {
for (int i = 0; i < 10; i++) {
printMsg();
}
}
public void printMsg() {
// get a reference to the thread running this
Thread t = Thread.currentThread();
String name = t.getName();
System.out.println("name=" + name);
}
public static void main(String[] args) {
TwoThreadAlive tt = new TwoThreadAlive();
tt.setName("my worker thread");
System.out.println("before start(), tt.isAlive()=" + tt.isAlive());
tt.start();
System.out.println("just after start(),tt.isAlive()=" + tt.isAlive());
for (int i = 0; i < 10; i++) {
tt.printMsg();
}
System.out
.println("at the end of main(), tt.isAlive()=" + tt.isAlive());
}}
这应该是
at the end of main(), tt.isAlive()=false
请帮帮我,这让我很生气。不,输出是正确的,因为当main方法执行最后一个println时,无法保证线程也已完成执行。添加一个tt.join;就在最后一次打印之前:
tt.join();
System.out
.println("at the end of main(), tt.isAlive()=" + tt.isAlive());
现在主线程将被阻塞,直到tt结束,因此println将仅在tt失效后执行
对于输出总是相同的情况,10是一个太细的粒度值,很可能每个线程在切换上下文时都完成了打印。尝试使用更大的值。不,输出是正确的,因为当main方法执行最后一个println时,无法保证线程也已完成执行。添加一个tt.join;就在最后一次打印之前:
tt.join();
System.out
.println("at the end of main(), tt.isAlive()=" + tt.isAlive());
现在主线程将被阻塞,直到tt结束,因此println将仅在tt失效后执行
对于输出总是相同的情况,10是一个太细的粒度值,很可能每个线程在切换上下文时都完成了打印。尝试使用更大的值。不是真正干净的可读代码,我认为printMsg应该是静态的,可能放在主类中。这样您就可以注意到它的行为并不依赖于自定义线程类。由于它打印当前线程名称,因此可以看到JVM在TwoThreadAlive线程和主线程之间切换的迭代次数更多。
关于isAlive问题,当主线程完成时,TwoThreadAlive线程可能尚未完成其执行。将主线程迭代次数更改为100,将自定义线程更改为10000,以查看此效果。不是真正干净的可读代码,我认为printMsg应该是静态的,可能放在主类中。这样您就可以注意到它的行为并不依赖于自定义线程类。由于它打印当前线程名称,因此可以看到JVM在TwoThreadAlive线程和主线程之间切换的迭代次数更多。
关于isAlive问题,当主线程完成时,TwoThreadAlive线程可能尚未完成其执行。将主线程迭代次数更改为100,将自定义线程更改为10000,以查看此效果。是否可以打印得到的输出…尝试增加for循环中的迭代次数。可能工作太少,并且没有执行上下文切换。将main方法内的循环增加到更高的值。你应该可以模拟一下。当前程序输出在其他机器上的方式不必相同,在运行程序时,调度线程由操作系统和其他参数决定。它在主方法循环中的运行时间为i=10000。是否可以打印得到的输出…尝试增加for循环中的迭代次数。可能工作太少,并且没有执行上下文切换。将main方法内的循环增加到更高的值。你应该可以模拟一下。在其他机器上,当前程序输出的方式不必相同,在运行程序时,调度线程由操作系统和其他参数决定。在主方法循环中,它对i=10000起作用。这意味着每次运行时,较小的值往往会给出相同的输出,那么,为什么作者在举一个例子的时候提到这些小值呢?这让人困惑。@Suman_Sohal:你有多核的还是单核的机器?在多核上更可能发生这种情况,因为线程确实是并行执行的,而在单核上则不是。也有可能是因为作者根本没有费心去测试他写的东西,但根据我的经验,只有10次迭代可能永远不会显示交错输出。我有64位Intel Xeon W3503。它有2个内核。这似乎是正确的……但如果我在任务管理器中将java.exe和javaw.exe关联更改为单CPU并重新启动服务,会有什么不同吗。我尝试过,但是它给出的是相同的输出。@Suman_Sohal,这里有很多因素需要考虑,比如控制台上的锁,它不能由两个线程同时更新,存储写入输出的数据的缓冲区,等等。这意味着每次运行时,较小的值往往会给出相同的输出,那么,为什么作者在举一个例子的时候提到这些小值呢?这让人困惑。@Suman_Sohal:你有多核的还是单核的机器?在多核上更可能发生这种情况,因为线程确实是并行执行的,而在单核上则不是。也有可能只是作者没有费心去实际测试他所写的东西,但根据我的经验,只有10次迭代将p
很可能永远不会向您显示交错输出。我有64位Intel Xeon W3503。它有两个内核。这似乎是正确的……但如果我在任务管理器中将java.exe和javaw.exe关联更改为单CPU并重新启动服务,会有什么不同吗。我尝试过,但它给出了相同的输出。@Suman_Sohal,这里有很多因素需要考虑,比如控制台上的锁,它不能由两个线程同时更新,缓冲区用来存储写入输出的数据,等等。