[改善Java代码]线程优先级只使用三个等级
线程的优先级(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代码]线程优先级只使用三个等级的更多相关文章
- [改善Java代码]列表相等只需关系元素数据
来看一个判断列表相等的例子,看代码: import java.util.ArrayList; import java.util.Vector; public class Client { public ...
- [改善Java代码]适时选择不同的线程池来实现
Java的线程池实现从最根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系,但是Java为了简化并行计算,还提供 ...
- [改善Java代码]优先选择线程池
在Java1.5之前,实现多线程编程比较麻烦,需要自己启动线程,并关注同步资源,防止线程死锁等问题,在1.5版本之后引入了并行计算框架,大大简化了多线程开发. 我们知道线程有5个状态:新建状态(New ...
- [改善Java代码]易变业务使用脚本语言编写
建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...
- [改善Java代码]不使用stop方法停止线程
线程启动完毕后,在运行可能需要终止,Java提供的终止方法只有一个stop,但是不建议使用此方法,因为它有以下三个问题: (1)stop方法是过时的 从Java编码规则来说,已经过时的方式不建议采用. ...
- [改善Java代码]异常只为异常服务
异常原本是正常逻辑的补充,但是有时候会被当做主逻辑使用.看如下代码: public class Client { enum Color { Red, Blue; } public static voi ...
- [改善Java代码]不要只替换一个类
建议20: 不要只替换一个类 我们经常在系统中定义一个常量接口(或常量类),以囊括系统中所涉及的常量,从而简化代码,方便开发,在很多的开源项目中已采用了类似的方法,比如在Struts2中,org.ap ...
- [改善Java代码]预防线程死锁
线程死锁DeadLock是多线程编码中最头疼的问题,也是最难重现的问题,因为Java是单进程多线程语言.
- [改善Java代码]多线程使用Vector或HashTable
Vector是ArrayList的多线程版本,HashTable是HashMap的多线程版本,这些概念我 们都很清楚,也被前辈嘱咐过很多次,但我们经常会逃避使用Vector和HashTable,因为用 ...
随机推荐
- [iOS基础控件 - 6.12.4] NavigationController vs TabBarController
A.属性 1. Item NavigationController: navigationItem (不需要创建) title rightBarButtonItems/ rightBarButtonI ...
- hbase 学习笔记一---基本概念
说在前面,本文部分内容来源于社区官网经过适度翻译,部分根据经验总结,部分是抄袭网络博文,(不一一列举引用,在此致歉)一并列在一起,本文的目的,希望能总结出一些有用的,应该注意到的东西,基本 ...
- 【Cocos2d-X开发学习笔记】第21期:动画类(CCAnimate)的使用
本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010 之前我们已经学习过一些方法让节点“动”起来,Co ...
- POJ 1664 放苹果 (递推)
题目链接:http://poj.org/problem?id=1664 dp[i][j]表示i个盘放j个苹果的方案数,dp[i][j] 可以由 dp[i - 1][j] 和 dp[i][j - i] ...
- baseadapter.getItemId的使用方法:实现listview筛选、动态删除
转载:http://www.lai18.com/content/1631131.html 这里的listview筛选是指listview的adapter实现filter来过滤数据. “动态删除&quo ...
- Unix-Linux编程实践 学习点滴
1.结构体最后定义一个char p[0]有什么作用 2. 3. 4. 1.结构体最后定义一个char p[0] 有什么作用 这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势: ...
- 【M22】考虑以操作符复合形式(op=)取代其独身形式(op)
1.对于内置类型,x = x+y 与x+=y的结果相同. 2. x=x+y 与 x+=y的结果相同,但二者做的事情差别很大. a.x=x+y做的事情:方法内有个局部对象,值为x+y,返回局部对象,返回 ...
- HDU 4813 Hard Code 水题
Hard Code Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.act ...
- 为joomla加入下拉菜单的方法
用 Joomla! 建站的大多数站长都须要在站点前台使用下拉菜单(dropdown menu),或者叫弹出菜单(slide menu),由于这样能够在有限的页面空间上公布很多其它的导航菜单,而且能够进 ...
- delphi 取得汉字的第一个字母
功能说明://取得汉字的第一个字母 function GetPYIndexChar( hzchar:string):char;begin caseWORD(hzchar[1])shl8+WORD(h ...