Java线程优先级

Java线程优先级,java,multithreading,Java,Multithreading,请参阅下面的代码。这是Oracle教程页面中经过修改的代码示例: public class BadThreads { static String message; private static class CorrectorThread extends Thread { public void run() { try { sleep(1000); } catch (InterruptedException e) {}

请参阅下面的代码。这是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之前执行main?线程c的优先级与其“父”线程main相同

是不是c可以看到main,因此c正在等待main返回?这没有道理,但这是我唯一能想到的

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

编辑: 替换

c.run(); 

同样的效果和更精细的编程

参见内联注释

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()
都将在不同的线程中调用
correctortorhread#run()
。这取决于
线程
调度程序,它将首先到达那里

在不调用
c.run()
的示例中,调度程序有时间调用

System.out.println("0: "+ message); // null

System.out.println("2: "+ message); // null

在另一个线程有时间初始化
消息之前

线程的全部要点是它们并行执行。因此,主线程与更正线程并行执行。由于纠错线程所做的第一件事是睡眠1秒,因此在纠错线程更改消息之前,主线程有足够的时间执行其指令。

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

c.start()
启动与主线程并行运行的线程
c.run()
,调用run函数,完成后转到下一个语句。

尝试如下操作:-

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

这一点都不奇怪,伙计,因为由于调用线程/方法的顺序不同,主线程不能保证第一个或第二个运行

首先
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秒,只是尝试打印消息并将值更改为“Mares not eat oats.”,然后再次打印,然后休眠2秒,然后坏线程在1秒后醒来(当主线程处于睡眠状态时),它更改消息的值并打印它,主线程在2秒钟后打印被坏线程更改的消息


答案就在这里,由于执行顺序的不同,对于哪个线程是第一个线程还是第二个线程没有任何保证。这可能会帮助你解决问题。如果你不是
root
administrator
的话,优先级只是一个提示,在很多情况下会被完全忽略。只有当你的CPU利用率很高的时候,我不建议你这样做。Peter Lawrey:我知道公平性是确保避免饥饿的一个原因——虽然不能保证第一轮等待时间最长的线程,但还没有听说CPU利用率很高(?)@PeterLawrey说,你唯一需要担心线程优先级的时候,就是当线程占用了所有的CPU,你想确保重要的线程得到适当的周期时。是的,没错。在一天的这个时候错过了时间差。thx。@Gray-在你编辑之前,他的答案看起来还可以。如果可以的话,我们当然可以。是的,时差。和我为泽山·莫卧儿写的评论一样。奇怪的是,你为什么选择了另一个答案,这个答案比这个答案晚,而且写得更糟糕@Roam@Roam这是一场比赛,一个线程设置
消息,另一个线程设置它。@Roam是的,这就是stackoverflow的工作原理。你要求澄清,我们给出答案它们。@Roam你的Q是
为什么main在c之前执行?
。我的答案是(和是)
c.start()和c.run()都将最终调用CorrectorThread#run(),但在不同的线程中。这取决于线程调度程序,它将首先到达那里。
然后你可以推断如果删除
c.run()会发生什么
…同时阅读您的原始答案,看看它在说什么。这太令人讨厌了。这里没有更多的评论。没有开始就不能运行。请您解释一下,让其他人可以学习。删除未注释的代码并不能教什么。
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.