-1

请参阅下面的代码。这是来自 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.

为什么main在c之前执行?线程c与其“父”线程main具有相同的优先级。

是否mainc可见,因此c正在等待main返回?这没有意义,但这是我唯一能想到的。

//==============================

编辑:替换

c.run(); 

c.join(); 

以获得相同的效果和更精细的编程。

4

5 回答 5

4

线程的全部意义在于它们并行执行。所以主线程与校正线程并行执行。而且由于校正线程所做的第一件事是休眠 1 秒钟,因此在校正线程更改消息之前,主线程有足够的时间执行其指令。

于 2013-10-21T12:24:55.530 回答
1

当您调用 时c.run(),它会执行 run 函数并等待完成。等待还将涵盖线程时间并行,您会在第一种情况下看到两个连续输出。在第二种情况下,线程启动并且 main 与 run 函数并行运行,因为 run 处于睡眠状态并且它涵盖了 main 显示的语句。

c.start()启动线程与 main 并行运行。 c.run(), 调用 run 函数并在完成时移至下一条语句。

于 2013-10-21T12:26:39.033 回答
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 秒后主线程打印由坏线程更改的消息。

答案就在这里,由于执行顺序,不能保证哪个线程先行或第二行。本教程可以帮助你,伙计。

于 2013-10-21T12:50:36.160 回答
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

于 2013-10-21T12:24:14.947 回答
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);
    }
}
于 2013-10-21T12:31:44.220 回答