如何在最高优先级线程之前执行最低优先级线程?

时间:2014-06-23 09:29:12

标签: java multithreading

执行此代码时,有时我注意到具有最低优先级的线程在具有最高优先级的线程之前执行。谁能帮助我理解这里发生了什么?

class Test implements Runnable 
{
    public void run()
    {
        for(int i=0; i<5; i++)
            System.out.println(Thread.currentThread().getName());
    }
}
class TestMain
{
    public static void main(String[] args)
    {
        Test test = new Test();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);

        t1.setPriority(Thread.MAX_PRIORITY);
        t1.setName("Max priority thread");

        t2.setPriority(Thread.MIN_PRIORITY);
        t2.setName("Min priority thread");

        t1.start();
        t2.start();
    }
}    

有时,我将输出视为

Min priority thread
Min priority thread
Min priority thread
Min priority thread
Max priority thread
Max priority thread
Max priority thread
Max priority thread
Max priority thread
Min priority thread

有时候是

Max priority thread
Max priority thread
Max priority thread
Max priority thread
Max priority thread
Min priority thread
Min priority thread
Min priority thread
Min priority thread
Min priority thread

逻辑上,具有最大优先级的线程应该首先启动。但有时它并没有发生。如果这是不可避免的,那么如何确保优先级最高的线程始终首先启动?

2 个答案:

答案 0 :(得分:2)

优先事项只是对调度程序的建议。 保证一个特定线程在另一个线程之前执行的唯一方法是使用适当的并发机制(例如CountDownLatch)自己完成。

答案 1 :(得分:1)

尝试使用 ExecutorService ForkJoinPool ,以便更好地控制您的主题。

这可能会对你有所帮助:

java.util.List<Thread> threads = new ArrayList<>();
for(int i = 0; i < 10; i++){
    threads.add(i, new Thread());
}
for(Thread thread : threads){
    thread.start();
    thread.wait(10);
}

编辑: ForkJoinPool 的示例:

    public void start() {
        final int parallelism = Runtime.getRuntime().availableProcessors();
        final ForkJoinPool forkJoinPool = new ForkJoinPool(parallelism);
        final List<ForkJoinTask<Thread>> tasks = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            tasks.add(i, newTask(forkJoinPool, i));
            tasks.get(i).invoke().start();
        }
        forkJoinPool.shutdown();
    }

    private ForkJoinTask<Thread> newTask(final ForkJoinPool pool, final int i) {
        return pool.submit(() -> new Thread(() -> {
            System.out.println("no " + i);
            Thread.sleep(50);
        })).fork();
    }

和输出:

no 0
no 1
no 2
no 3
no 4
no 5
no 6
no 7
no 8
no 9
no 10
no 12
no 11
no 13
no 14
no 15
no 16
no 17
no 18
no 19
no 20
no 21
no 22
no 23
no 24
no 25
no 26
no 27
no 28
no 29
no 30
no 31
no 32
no 34
no 37
no 38
no 36
no 33
no 35
no 40
no 39
no 41
no 42
no 43
no 44
no 45
no 46
no 47
no 48
no 49
no 50
no 51
no 52
no 53
no 54
no 55
no 56
no 57
no 58
no 59
no 61
no 60
no 62
no 63
no 64
no 65
no 66
no 67
no 69
no 68
no 70
no 72
no 71
no 73
no 74
no 75
no 76
no 78
no 77
no 79
no 80
no 81
no 82
no 84
no 83
no 85
no 86
no 87
no 88
no 89
no 90
no 91
no 92
no 93
no 94
no 96
no 95
no 97
no 98
no 99