java的线程优先级

今天看了下里面的一段关于java线程优先级的代码.奇怪于它的运行结果,二话不说,直接运行代码测试.

代码:

package bookcode.twentyfirst;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SimplePriorities implements Runnable {

	private int countDown = 5;
	
	private volatile double d;
	
	private int priority;
	
	public SimplePriorities(int priority){
		this.priority = priority;
	}
	
	public String toString(){
		return Thread.currentThread() + ":" + countDown;
	}
	
	@Override
	public void run() {
		Thread.currentThread().setPriority(priority);
		while(true){
			for(int i = 1; i < 100000; i++){
				d += (Math.PI + Math.E) / i;
				if(i % 1000 == 0){
					Thread.yield();
				}
				System.out.println(this);
				if(--countDown == 0){
					return;
				}
			}
		}
	}
	
	public static void main(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool();
		for(int i = 0; i < 5; i++){
			exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
		}
		exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
		exec.shutdown();
	}
}

运行结果:

Thread[pool-1-thread-2,1,main]:5
Thread[pool-1-thread-2,1,main]:4
Thread[pool-1-thread-6,10,main]:5
Thread[pool-1-thread-6,10,main]:4
Thread[pool-1-thread-6,10,main]:3
Thread[pool-1-thread-6,10,main]:2
Thread[pool-1-thread-6,10,main]:1
Thread[pool-1-thread-1,1,main]:5
Thread[pool-1-thread-1,1,main]:4
Thread[pool-1-thread-1,1,main]:3
Thread[pool-1-thread-1,1,main]:2
Thread[pool-1-thread-1,1,main]:1
Thread[pool-1-thread-3,1,main]:5
Thread[pool-1-thread-3,1,main]:4
Thread[pool-1-thread-3,1,main]:3
Thread[pool-1-thread-3,1,main]:2
Thread[pool-1-thread-2,1,main]:3
Thread[pool-1-thread-5,1,main]:5
Thread[pool-1-thread-5,1,main]:4
Thread[pool-1-thread-5,1,main]:3
Thread[pool-1-thread-5,1,main]:2
Thread[pool-1-thread-5,1,main]:1
Thread[pool-1-thread-4,1,main]:5
Thread[pool-1-thread-4,1,main]:4
Thread[pool-1-thread-4,1,main]:3
Thread[pool-1-thread-4,1,main]:2
Thread[pool-1-thread-4,1,main]:1
Thread[pool-1-thread-2,1,main]:2
Thread[pool-1-thread-3,1,main]:1
Thread[pool-1-thread-2,1,main]:1

运行结果:

Thread[pool-1-thread-1,1,main]:5
Thread[pool-1-thread-2,1,main]:5
Thread[pool-1-thread-6,10,main]:5
Thread[pool-1-thread-5,1,main]:5
Thread[pool-1-thread-3,1,main]:5
Thread[pool-1-thread-5,1,main]:4
Thread[pool-1-thread-6,10,main]:4
Thread[pool-1-thread-2,1,main]:4
Thread[pool-1-thread-1,1,main]:4
Thread[pool-1-thread-1,1,main]:3
Thread[pool-1-thread-1,1,main]:2
Thread[pool-1-thread-4,1,main]:5
Thread[pool-1-thread-1,1,main]:1
Thread[pool-1-thread-2,1,main]:3
Thread[pool-1-thread-6,10,main]:3
Thread[pool-1-thread-6,10,main]:2
Thread[pool-1-thread-6,10,main]:1
Thread[pool-1-thread-5,1,main]:3
Thread[pool-1-thread-5,1,main]:2
Thread[pool-1-thread-5,1,main]:1
Thread[pool-1-thread-3,1,main]:4
Thread[pool-1-thread-2,1,main]:2
Thread[pool-1-thread-4,1,main]:4
Thread[pool-1-thread-2,1,main]:1
Thread[pool-1-thread-3,1,main]:3
Thread[pool-1-thread-3,1,main]:2
Thread[pool-1-thread-3,1,main]:1
Thread[pool-1-thread-4,1,main]:3
Thread[pool-1-thread-4,1,main]:2
Thread[pool-1-thread-4,1,main]:1

这个运行结果和书上说的不尽相同.难道这个优先级不起作用.?

确实是这样的,JDK有10个优先级,但它与大多数操作系统映射得并不好.书上原话是:尽量使用MAX_PRIORITY,NORM_PRIORITY和MIN_PRIORITY.

不过,事情没这么简单.我们的代码用的就是这些优先级.

根据http://www.javamex.com/tutorials/threads/priority.shtml

Problems with thread priorities


The notion that some threads should have a higher "priority" than others is an intuitive idea. However, there are a couple of caveats with thread priorities that we need to beware of:


depending on your OS and VM version, Thread.setPriority()may actually do nothing at all(see below for details);


what thread priorities mean to the thread scheduler differs from scheduler to scheduler, and may not be what you intuitively presume; in particular:


Priority may not indicate "share of the CPU".
(As we'll see below, it turns out that "priority" is more or less an indication of CPU distribution on UNIX systems, but not under Windows.)


thread priorities are usually a combination of "global" and "local" priority settings, and Java's setPriority() method typically works only on the local priority— in other words, you can't set priorities across the entire range possible (this is actually a form of protection— you generally don't want, say, the mouse pointer thread or a thread handling audio data to be preempted by some random user thread);


the number of distinct priorities available differs from system to system, but Java defines 10 (numbered 1-10 inclusive), so you could end up with threads that have different priorities under one OS, but the same priority (and hence unexpected behaviour) on another;


a system could (and typically does) add some OS-specific behaviour to threads depending on their priority (e.g. "only give a quantum boost if the priority is below X")— so again, part of what "priority" means differs from system to system;


most operating systems' thread schedulers actually perform temporary manipulations to thread priorities at strategic points (e.g. when a thread receives an event or I/O it was waiting for), and often "the OS knows best"; trying to manually manipulate priorities could just interfere with this system;


your application doesn't generally know what threads are running in other processes, so the effect on the overall system of changing the priority of a thread may be hard to predict. So you might find, for example, that your low-priority thread designed to "run sporadically in the background" hardly runs at all due to a virus dection program running at a slightly higher (but still 'lower-than-normal') priority, and that the performance unpredictably varies depending on which antivirus program your customer is using. Of course, effects like these will always happen to some extent or other on modern systems.


翻译如下:

Thread.setPriority()可能根本不做任何事情,这跟你的操作系统和虚拟机版本有关
* 线程优先级对于不同的线程调度器可能有不同的含义,可能并不是你直观的推测。特别地,优先级并不一定是指CPU的分享。在UNIX系统,优先级或多或少可以认为是CPU的分配,但Windows不是这样
* 线程的优先级通常是全局的和局部的优先级设定的组合。Java的setPriority()方法只应用于局部的优先级。换句话说,你不能在整个可能的范围 内设定优先级。(这通常是一种保护的方式,你大概不希望鼠标指针的线程或者处理音频数据的线程被其它随机的用户线程所抢占)
* 不同的系统有不同的线程优先级的取值范围,但是Java定义了10个级别(1-10)。这样就有可能出现几个线程在一个操作系统里有不同的优先级,在另外一个操作系统里却有相同的优先级(并因此可能有意想不到的行为)
* 操作系统可能(并通常这么做)根据线程的优先级给线程添加一些专有的行为(例如”only give a quantum boost if the priority is below X“)。这里再重复一次,优先级的定义有部分在不同系统间有差别。
* 大多数操作系统的线程调度器实际上执行的是在战略的角度上对线程的优先级做临时操作(例如当一个线程接收到它所等待的一个事件或者I/O),通常操作系统知道最多,试图手工控制优先级可能只会干扰这个系统。
* 你的应用程序通常不知道有哪些其它进程运行的线程,所以对于整个系统来说,变更一个线程的优先级所带来的影响是难于预测的。例如你可能发现,你有一个预期 为偶尔在后台运行的低优先级的线程几乎没有运行,原因是一个病毒监控程序在一个稍微高一点的优先级(但仍然低于普通的优先级)上运行,并且无法预计你程序 的性能,它会根据你的客户使用的防病毒程序不同而不同。


基于以上原因,得出以下结论:

不要假定高优先级的线程一定先于低优先级的线程执行,不要有逻辑依赖于线程优先级,否则可能产生意外结果.

你可能感兴趣的:(java)