Java线程优先级

时间:2013-10-21 12:19:50

标签: java multithreading

请参阅下面的代码。这是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(); 

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

5 个答案:

答案 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);
    }
}