2014-06-23 73 views
0

执行此代码时,有时我会注意到具有最低优先级的线程在具有最高优先级的线程之前执行。任何人都可以帮助我理解这里发生了什么?在最大优先级线程之前,最低优先级线程是如何执行的?

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 

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

+3

线程无需根据其优先级执行。最终,它决定何时执行哪个线程的操作系统。你给的优先级只是一个建议。 – TheLostMind

+5

我认为线程优先级只是对底层操作系统的推荐。不能保证哪个线程会首先被执行。 – clamp

+0

@TheLostMind:那么是否有任何方法或算法可以确保首先执行特定的线程? –

回答

2

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

+0

不知道'CountDownLatch'。这真的有帮助。谢谢。 –

1

尝试使用的ExecutorServiceForkJoinPool,以你的线程更好的控制。

,可能这将帮助你:

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 
+0

@NullPointer对您有帮助吗? – AvB

+0

是的。谢谢你提出一个更多的方法。 –

+0

不客气,祝你好运:) – AvB