线程的优先级(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. homework-附加题:第12章基本数据类型阅读总结

    基本数据类型是构建其他所有数据类型的构造块,本人认为这部分是计算机编程的基础,值得得到大家的注意. 首先,在本章中作者提到了避免使用magic number.使用magic number这种做法是极其 ...

  2. 【转】新建maven工程为什么jdk会是默认版本 而不是自己设置的版本?

    原文链接:为什么我eclipse新建项目的时候默认的是JRE1.5? 修改Maven中conf目录里的setting.xml文件内容,加上如下内容: <profiles> <!-- ...

  3. [iOS 多线程 & 网络 - 2.4] - 大文件下载 (边下边写/暂停恢复下载/压缩解压zip/多线程下载)

    A.需求 边下边写入硬盘 显示下载进度 暂停/恢复 下载 解压文件 多线程下载   B.基本知识 1.小文件下载 如果文件比较小,下载方式会比较多直接用NSData的+ (id)dataWithCon ...

  4. [iOS UI进阶 - 3.2] 手势识别器UIGestureRecognizer

    A.系统提供的手势识别器   1.敲击手势 UITapGestureRecognizer numberOfTapsRequired: 敲击次数 numberOfTouchesRequired: 同时敲 ...

  5. java 2 8 10 16

    An integer literal may be expressed in decimal (base 10), hexadecimal (base 16), octal (base 8), or ...

  6. 使用 DllImport 属性

    本主题说明 DllImport 属性的常见用法.第一节讨论使用 DllImport 从托管应用程序调用本机代码的优点.第二节集中讨论封送处理和 DllImport 属性的各个方面. 从托管应用程序调用 ...

  7. java命令行运行jar里的main类

    一般运行包含manifest的jar包,可以使用 java -jar <jar-file-name>.jar 如果jar里没有 manifest,则可以使用 java -cp foo.ja ...

  8. 方差分析(ANOVA)(转)

    转自:http://blog.sciencenet.cn/blog-116082-218338.html 方差分析(analysis of variance,ANOVA),即变量分析,是对多个样本平均 ...

  9. securecrt 连接vmware ubuntu

    折腾了好几天,我只想说shit,吃一堑长一智,和大家分享. SecureCRT连接Linux是使用Ubuntu下的SSH服务,ssh包括客户端和服务端即openssh-client,openssh-s ...

  10. 445port入侵具体解释

    445port入侵具体解释   关于"445port入侵"的内容445port入侵具体解释本站搜索很多其它关于"445port入侵"的内容 445port入侵, ...