[改善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,因为用 ...
随机推荐
- homework-附加题:第12章基本数据类型阅读总结
基本数据类型是构建其他所有数据类型的构造块,本人认为这部分是计算机编程的基础,值得得到大家的注意. 首先,在本章中作者提到了避免使用magic number.使用magic number这种做法是极其 ...
- 【转】新建maven工程为什么jdk会是默认版本 而不是自己设置的版本?
原文链接:为什么我eclipse新建项目的时候默认的是JRE1.5? 修改Maven中conf目录里的setting.xml文件内容,加上如下内容: <profiles> <!-- ...
- [iOS 多线程 & 网络 - 2.4] - 大文件下载 (边下边写/暂停恢复下载/压缩解压zip/多线程下载)
A.需求 边下边写入硬盘 显示下载进度 暂停/恢复 下载 解压文件 多线程下载 B.基本知识 1.小文件下载 如果文件比较小,下载方式会比较多直接用NSData的+ (id)dataWithCon ...
- [iOS UI进阶 - 3.2] 手势识别器UIGestureRecognizer
A.系统提供的手势识别器 1.敲击手势 UITapGestureRecognizer numberOfTapsRequired: 敲击次数 numberOfTouchesRequired: 同时敲 ...
- java 2 8 10 16
An integer literal may be expressed in decimal (base 10), hexadecimal (base 16), octal (base 8), or ...
- 使用 DllImport 属性
本主题说明 DllImport 属性的常见用法.第一节讨论使用 DllImport 从托管应用程序调用本机代码的优点.第二节集中讨论封送处理和 DllImport 属性的各个方面. 从托管应用程序调用 ...
- java命令行运行jar里的main类
一般运行包含manifest的jar包,可以使用 java -jar <jar-file-name>.jar 如果jar里没有 manifest,则可以使用 java -cp foo.ja ...
- 方差分析(ANOVA)(转)
转自:http://blog.sciencenet.cn/blog-116082-218338.html 方差分析(analysis of variance,ANOVA),即变量分析,是对多个样本平均 ...
- securecrt 连接vmware ubuntu
折腾了好几天,我只想说shit,吃一堑长一智,和大家分享. SecureCRT连接Linux是使用Ubuntu下的SSH服务,ssh包括客户端和服务端即openssh-client,openssh-s ...
- 445port入侵具体解释
445port入侵具体解释 关于"445port入侵"的内容445port入侵具体解释本站搜索很多其它关于"445port入侵"的内容 445port入侵, ...