Thread.setPriority() 从 1 到 10 提供了看似精细的十档优先级,但这篇真实测出来的结果会让人怀疑这套 API 的实际价值——高优先级线程,真实并不总是跑得比低优先级线程快。
上一篇:守护线程真实验证
两个线程同时空转自增计数器 500 毫秒,一个设为最低优先级,一个设为最高优先级,真实统计各自的计数结果。
ThreadPriorityDemo.java Thread low = new Thread(() -> { while (!stop.get()) lowCount.incrementAndGet(); }); Thread high = new Thread(() -> { while (!stop.get()) highCount.incrementAndGet(); }); low.setPriority(Thread.MIN_PRIORITY); // 1 high.setPriority(Thread.MAX_PRIORITY); // 10
第1轮: MIN_PRIORITY空转次数=18349389, MAX_PRIORITY空转次数=19061882, 比例=1.04 第2轮: MIN_PRIORITY空转次数=44771468, MAX_PRIORITY空转次数=31776327, 比例=0.71 第3轮: MIN_PRIORITY空转次数=20070484, MAX_PRIORITY空转次数=18228503, 比例=0.91
真实结果比预想的更极端:三轮测试里,MAX_PRIORITY 线程只有第一轮真实"占优"(比例1.04,优势也很微弱),第二轮真实是 MIN_PRIORITY 线程完成的工作量反超了 43%(比例0.71,意味着"最低优先级"线程比"最高优先级"线程多做了将近一半的工作),第三轮依然是低优先级线程领先。
如果业务上真实需要"某些任务优先处理"这样的语义,更可靠的做法是使用显式的优先级队列(比如给 ThreadPoolExecutor 配一个 PriorityBlockingQueue,让任务按优先级顺序被取出执行),而不是依赖 Thread.setPriority() 这种系统调度层面的、真实不确定的机制。这也是系列前面验证过的 线程池拒绝策略所在的同一层面问题:并发控制应该用语言/框架提供的确定性机制去实现,而不是寄希望于底层调度器的"善意"。
每一行都是真实运行这段代码得到的结果。