线程的优先级(priority)决定了线程获得CPU运行的机会,优先级越高获得的运行机会越大,优先级越低获得的机会越小.Java的线程有10个级别(准确的说是11个级别,级别为0的线程是JVM,应用程序不能设置该级别)

那是不是级别为10的线程肯定比级别为9的线程优先运行呢?

看代码:

 public class Client {
public static void main(String[] args){
//启动20个不同优先级的线程
for (int i = 0; i < 20; i++) {
new TestThread().start(i % 10 + 1);
} }
} class TestThread implements Runnable {
//启动线程
public void start(int _priority) {
Thread t = new Thread(this);
//设置线程优先级
t.setPriority(_priority);
t.start();
} @Override
public void run() {
//消耗CPU的计算,性能差的机器,请修改循环限制
for (int i = 0; i < 100000; i++) {
Math.hypot(Math.pow(924526789,i),Math.cos(i));
}
//输出线程优先级
System.out.println("Priority:" + Thread.currentThread().getPriority()); }
}

该多线程类实现了Runnable接口,实现了run方法,注意在run方法中有一个比较占用CPU的计算,该计算毫无意义,只是为了保证一个线程尽可能多的消耗CPU资源,目的是为了观察在CPU繁忙时,不同优先级线程的执行顺序.

需要说明的是,如果此处使用了Thread.sleep()方法,则不能体现出线程优先级的本质了,因为CPU并不繁忙,线程调度不会遵循优先级顺序来进行调度.

上面代码创建了20个线程,每个线程在运行时都耗尽了CPU资源,因为优先级不同,线程调度应该最先处理优先级最高的,然后处理优先级最低的,也就是先执行了2个优先级为10的线程,然后执行2个优先级为9的线程,2个优先级为8的线程....是结果并不是这样的...

运行结果:

Priority:10
Priority:7
Priority:1
Priority:8
Priority:3
Priority:6
Priority:3
Priority:2
Priority:4
Priority:8
Priority:9
Priority:9
Priority:10
Priority:2
Priority:6
Priority:7
Priority:5
Priority:5
Priority:4
Priority:1

println方法虽然有输出损耗,可能会影响到输出结果,但是不管运行多少次,都有两个不争的事实.

(1)并不是严格遵守线程优先级别来执行的.

  因为优先级只是代表获得CPU运行的机会,并不代表强制的排序号.

(2)优先级差别越大,运行机会差别越明显. 

  比如优先级为10的线程通常比优先级为2的线程先执行,但是优先级为6的线程和优先级为5的线程差别就不太明显了.

这连个现象是优先级的一个重要表现:

因为线程运行是要获得CPU资源的,谁能决定哪个线程先获得哪个线程后获得呢?

这是依照操作系统设定的线程优先级来分配的,每个线程需要运行,需要操作系统分配优先级和CPU资源,对Java来说,JVM调用操作系统的接口设置优先级,比如Windows操作系统是通过调用SetThreadPriority函数来设置的.

不同的操作系统线程的优先级是不相同的,Windows7个优先级,Linux有140个优先级,Freebsd则有255个(此处指的是优先级总数,不同操作系统有不同的分类,如中断线程,操作系统等级等,各个操作系统具体用户可用的线程数量也不相同).

Java是跨平台的系统,需要把10个优先级映射成不同操作系统的优先级,于是界定了Java的优先级只是代表抢占CPU的机会大小,优先级越高,抢占CPU的机会越大.被执行的可能性越高.

Java的缔造者们也发现了这个问题,于是在Thread类中设置了三个优先级,建议使用优先级常量,而不是1到10的随机数字.

public class Thread implements Runnable {
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1; /**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5; /**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
}

建议使用这三个级别,不建议使用其他7个数字.

如果优先级相同,怎么办?

这也是由操作系统决定的,基本上是按照FIFO的原则,但是也不能完全保证.

[改善Java代码]线程优先级只使用三个等级的更多相关文章

  1. [改善Java代码]列表相等只需关系元素数据

    来看一个判断列表相等的例子,看代码: import java.util.ArrayList; import java.util.Vector; public class Client { public ...

  2. [改善Java代码]适时选择不同的线程池来实现

    Java的线程池实现从最根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系,但是Java为了简化并行计算,还提供 ...

  3. [改善Java代码]优先选择线程池

    在Java1.5之前,实现多线程编程比较麻烦,需要自己启动线程,并关注同步资源,防止线程死锁等问题,在1.5版本之后引入了并行计算框架,大大简化了多线程开发. 我们知道线程有5个状态:新建状态(New ...

  4. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  5. [改善Java代码]不使用stop方法停止线程

    线程启动完毕后,在运行可能需要终止,Java提供的终止方法只有一个stop,但是不建议使用此方法,因为它有以下三个问题: (1)stop方法是过时的 从Java编码规则来说,已经过时的方式不建议采用. ...

  6. [改善Java代码]异常只为异常服务

    异常原本是正常逻辑的补充,但是有时候会被当做主逻辑使用.看如下代码: public class Client { enum Color { Red, Blue; } public static voi ...

  7. [改善Java代码]不要只替换一个类

    建议20: 不要只替换一个类 我们经常在系统中定义一个常量接口(或常量类),以囊括系统中所涉及的常量,从而简化代码,方便开发,在很多的开源项目中已采用了类似的方法,比如在Struts2中,org.ap ...

  8. [改善Java代码]预防线程死锁

    线程死锁DeadLock是多线程编码中最头疼的问题,也是最难重现的问题,因为Java是单进程多线程语言.

  9. [改善Java代码]多线程使用Vector或HashTable

    Vector是ArrayList的多线程版本,HashTable是HashMap的多线程版本,这些概念我 们都很清楚,也被前辈嘱咐过很多次,但我们经常会逃避使用Vector和HashTable,因为用 ...

随机推荐

  1. html5 标签

    按字母顺序排列的标签列表 4: 指示在 HTML 4.01 中定义了该元素 5: 指示在 HTML 5 中定义了该元素 标签 描述 4 5 <!--...--> 定义注释. 4 5 < ...

  2. HDU 5826 physics (积分推导)

    physics 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5826 Description There are n balls on a smoo ...

  3. javascript中数组的迭代等操作

  4. 转载 C#使用Salt + Hash来为密码加密

    转载 http://www.csharpwin.com/csharpspace/13412r9615.shtml (一) 为什么要用哈希函数来加密密码 如果你需要保存密码(比如网站用户的密码),你要考 ...

  5. POJ 1088 滑雪 (记忆化搜索)

    题目链接:http://poj.org/problem?id=1088 题意很好懂,就是让你求一个最长下降路线的长度. dp[i][j]记录的是i j这个位置的最优的长度,然后转移方程是dp[i][j ...

  6. CodeForces 705A Hulk (水题)

    题意:输入一个 n,让你输出一行字符串. 析:很水题,只要判定奇偶性,输出就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,10240 ...

  7. CSS构造超链接

    超链接边框 派生超链接 属性选择器超链接 动态超链接 图像翻转超链接 CSS工具提示 1.给链接加上边框     A:link {         Color: #f00;         Text- ...

  8. 在VS.NET中根据条件设置不同的MainForm

    在VS.NET中有时候需要根据不同的条件设置不同的MainForm,例如:在程序第一次运行时候打开设置基本信息或服务器信息窗口等. 1.找到VS.NET中设置MainForm的窗口: 2.在编辑窗口中 ...

  9. cocos2d-x 缓动曲线

    转自:http://blog.csdn.net/cocos2der/article/details/7261808 在实现运动中,我们常常需要实现一些加速度或者减速度的效果,cocos2d-x引擎为我 ...

  10. Android常用正则工具类

    此类提供日常开发中常用的正则验证函数,比如:邮箱.手机号.电话号码.身份证号码.日期.数字.小数.URL.IP地址等.使用Pattern对象的matches方法进行整个字符匹配,调用该方法相当于:   ...