Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java线程编程示例-程序运行异常_Java_Multithreading - Fatal编程技术网

Java线程编程示例-程序运行异常

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

我正在读保罗·海德的《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 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,这里有很多因素需要考虑,比如控制台上的锁,它不能由两个线程同时更新,缓冲区用来存储写入输出的数据,等等。