转载请注明出处
http://blog.csdn.net/pony_maggie/article/details/43889225
作者:小马
Java线程的优先级取值范围是1 (Thread.MIN_PRIORITY ) 到 10 (Thread.MAX_PRIORITY )。如果没有设置, 线程默认的优先级是NORM_PRIORITY。这个值是5。
demo创建了10个线程实例,可以看到每个线程当前的优先级并可以修改这个优先级。程序运行的效果如下,
如图所示,10个ticker实例,可以通过up,down来控制它的优先级并可以实时显示出来。
class Ticker2 extends Thread { private JButton b = new JButton("Toggle"); private JButton incPriority = new JButton("up"); private JButton decPriority = new JButton("dwon"); private JTextField t = new JTextField(10), pr = new JTextField(3); //display priority private int count = 0; private boolean runFlag = true; public Ticker2(Container c) { b.addActionListener(new ToggleL()); incPriority.addActionListener(new UpL()); decPriority.addActionListener(new DownL()); //这里新建panel的目的是为了分组,因为ticker要创建数组,这样每个实例都有自己的panel JPanel p = new JPanel(); p.add(t); p.add(pr); p.add(b); p.add(incPriority); p.add(decPriority); c.add(p);//这里直接用container应该也行,不用加panel // } class ToggleL implements ActionListener { public void actionPerformed(ActionEvent e) { runFlag = !runFlag; } } class UpL implements ActionListener { public void actionPerformed(ActionEvent e) { //Java线程的优先级取值范围是1 (Thread.MIN_PRIORITY ) 到 10 (Thread.MAX_PRIORITY )。 int newPriority = getPriority() + 1; //每次递增 if(newPriority > Thread.MAX_PRIORITY) { newPriority = Thread.MAX_PRIORITY; } setPriority(newPriority); } } class DownL implements ActionListener { public void actionPerformed(ActionEvent e) { int newPriority = getPriority() - 1; if(newPriority < Thread.MIN_PRIORITY) { newPriority = Thread.MIN_PRIORITY; } setPriority(newPriority); } } public void run() { while(true) { if(runFlag) { t.setText(Integer.toString(count++)); pr.setText(Integer.toString(getPriority())); } //yield方法让同优先级的线程有执行的机会。 yield(); } } }
每个ticker,第一个框显示的是个计数器,表示当前线程第几次获得执行机会,第二框显示的是线程的当前优先级。注意到,一开始的线程都是值为4的优先级,这是因为线程组有个最高优先级的概念,组里的所有线程最高都不能超过这个优先级。可以试试点击up按钮,最大只能到group max priority。这个值是4。
public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); for(int i = 0; i < s.length; i++) { s[i] = new Ticker2(cp); } cp.add(new JLabel("MAX_PRIORITY = " + Thread.MAX_PRIORITY)); cp.add(new JLabel("MIN_PRIORITY = " + Thread.MIN_PRIORITY)); cp.add(new JLabel("Group max priority")); cp.add(mp); cp.add(start); cp.add(upMax); cp.add(downMax); start.addActionListener(new StartL()); upMax.addActionListener(new UpMaxL()); downMax.addActionListener(new DownMaxL()); showMaxPriority(); //recursively display parent thread group ThreadGroup parent = s[0].getThreadGroup().getParent(); while(parent != null) { cp.add(new Label("parent threadgroup max priority = " + parent.getMaxPriority())); parent = parent.getParent(); } }
在Java中每一个线程都归属于某个线程组管理的一员,例如在主函数main()主工作流程中产生一个线程,则产生的线程属于main这个线程组管理的一员。简单地说,线程组(ThreadGroup)就是由线程组成的管理线程的类,这个类是java.lang.ThreadGroup类。
线程组的最大优先级理论上来说应该是Thread.MAX_PRIORITY,但是实际情况往往比较复杂,下面是摘抄、翻译自JAVAMEX -> Java threading introduction -> Thread priorioties
对于线程优先级,我们需要注意:
* 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),通常操作系统知道最多,试图手工控制优先级可能只会干扰这个系统。
* 你的应用程序通常不知道有哪些其它进程运行的线程,所以对于整个系统来说,变更一个线程的优先级所带来的影响是难于预测的。例如你可能发现,你有一个预期 为偶尔在后台运行的低优先级的线程几乎没有运行,原因是一个病毒监控程序在一个稍微高一点的优先级(但仍然低于普通的优先级)上运行,并且无法预计你程序 的性能,它会根据你的客户使用的防病毒程序不同而不同。