[改善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,因为用 ...
随机推荐
- HTML+CSS+JS学习总结
HTML: 什么是 HTML? HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种标记 ...
- 问题-PopupMenu是哪个控件调用弹出的?
相关资料: http://bbs.csdn.net/topics/310195683 问题现象:今天有朋友问我个简单的问题,在多个Edit上弹出菜单,怎么判断是哪个Edit调用的.我想了想这个我还真不 ...
- Unity3D之Mecanim动画系统学习笔记(七):IK(反向动力学)动画
什么是IK? IK(Inverse Kinematics)即反向动力学,即可以使用场景中的各种物体来控制和影响角色身体部位的运动,一般来说骨骼动画都是传统的从父节点到子节点的带动方式(即正向动力学), ...
- Java Thread Basic
一.Java的多线程有三种实现方式. 1.继承创建. a.定义子类,重写run方法 b.创建Thread子类的实例(即现成对象) c.调用start() 方法启动现成 特征:不可以共享变量. publ ...
- SQL Select count(*)和Count(1)的区别和执行方式及SQL性能优化
SQL性能优化:http://www.cnblogs.com/CareySon/category/360333.html Select count(*)和Count(1)的区别和执行方式 在SQL S ...
- 使用gcc编译gdb调试
gcc 在linux系统中,默认是没有安装gcc编译器的,可以通过命令 rpm -q | grep gcc 来查看.安装命令为: yum -y install gcc 安装后,编写一个.c结尾的文件. ...
- Windows 环境下于虚拟环境安装源码安装 cx_oracle
安装前提条件: (1).安装 instantclient-basic-nt (2).安装 instantclient-sdk-nt (3).安装 Microsoft Visual C++ Compil ...
- HCTF2016-杂项签到
题目下载了一个+_+.pcapng ,用Wireshark打开, Ctrl-F搜索flag 发现python代码 将Data导出 #!/usr/bin/env python # coding:utf- ...
- “WinMount”和“云端”真是相当好用!
WinMount作为一款压缩文件管理以及虚拟光驱工具已经无敌了.更有两项功能相当好用: 1.将rar.zip等压缩文件直接虚拟成磁盘,也就是下载一个7G的游戏可以不用解压直接安装了! 2.右键压缩文件 ...
- Python 类型的分类
1.存储模型,对象可以保存多少个值.如果只能保存一个值,是原子类型.如果可以保存多个值,是容器类型.数值是原子类型,元组,列表,字典是容器类型.考虑字符串,按道理,字符串应该是容器类型,因为它包含多个 ...