Java知多少(61)线程优先级
线程优先级被线程调度用来判定何时每个线程允许运行。理论上,优先级高的线程比优先级低的线程获得更多的CPU时间。实际上,线程获得的CPU时间通常由包括优先级在内的多个因素决定(例如,一个实行多任务处理的操作系统如何更有效的利用CPU时间)。
一个优先级高的线程自然比优先级低的线程优先。举例来说,当低优先级线程正在运行,而一个高优先级的线程被恢复(例如从沉睡中或等待I/O中),它将抢占低优先级线程所使用的CPU。
理论上,等优先级线程有同等的权利使用CPU。但你必须小心了。记住,Java是被设计成能在很多环境下工作的。一些环境下实现多任务处理从本质上与其他环境不同。为安全起见,等优先级线程偶尔也受控制。这保证了所有线程在无优先级的操作系统下都有机会运行。实际上,在无优先级的环境下,多数线程仍然有机会运行,因为很多线程不可避免的会遭遇阻塞,例如等待输入输出。遇到这种情形,阻塞的线程挂起,其他线程运行。
但是如果你希望多线程执行的顺利的话,最好不要采用这种方法。同样,有些类型的任务是占CPU的。对于这些支配CPU类型的线程,有时你希望能够支配它们,以便使其他线程可以运行。
设置线程的优先级,用setPriority()方法,该方法也是Tread 的成员。它的通常形式为:
final void setPriority(int level)
这 里 , level 指 定了对所调用的线程的新的优先权的设置。Level的值必须在MIN_PRIORITY到MAX_PRIORITY范围内。通常,它们的值分别是1和10。要返回一个线程为默认的优先级,指定NORM_PRIORITY,通常值为5。这些优先级在Thread中都被定义为final型变量。
你可以通过调用Thread的getPriority()方法来获得当前的优先级设置。该方法如下:
final int getPriority( )
当涉及调度时,Java的执行可以有本质上不同的行为。Windows 95/98/NT/2000 的工作或多或少如你所愿。但其他版本可能工作的完全不同。大多数矛盾发生在你使用有优先级行为的线程,而不是协同的腾出CPU时间。最安全的办法是获得可预先性的优先权,Java获得跨平台的线程行为的方法是自动放弃对CPU的控制。
下面的例子阐述了两个不同优先级的线程,运行于具有优先权的平台,这与运行于无优先级的平台不同。一个线程通过Thread.NORM_PRIORITY设置了高于普通优先级两级的级数,另一线程设置的优先级则低于普通级两级。两线程被启动并允许运行10秒。每个线程执行一个循环,记录反复的次数。10秒后,主线程终止了两线程。每个线程经过循环的次数被显示。
// Demonstrate thread priorities.
class clicker implements Runnable {
int click = 0;
Thread t;
private volatile boolean running = true;
public clicker(int p) {
t = new Thread(this);
t.setPriority(p);
} public void run() {
while (running) {
click++;
}
} public void stop() {
running = false;
} public void start() {
t.start();
}
} class HiLoPri {
public static void main(String args[]) {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
clicker hi = new clicker(Thread.NORM_PRIORITY + 2);
clicker lo = new clicker(Thread.NORM_PRIORITY - 2);
lo.start();
hi.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
lo.stop();
hi.stop();
// Wait for child threads to terminate.
try {
hi.t.join();
lo.t.join();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
} System.out.println("Low-priority thread: " + lo.click);
System.out.println("High-priority thread: " + hi.click);
}
}
该程序在Windows 98下运行的输出,表明线程确实上下转换,甚至既不屈从于CPU,也不被输入输出阻塞。优先级高的线程获得大约90%的CPU时间。
Low-priority thread: 4408112
High-priority thread: 589626904
当然,该程序的精确的输出结果依赖于你的CPU的速度和运行的其他任务的数量。当同样的程序运行于无优先级的系统,将会有不同的结果。
上述程序还有个值得注意的地方。注意running前的关键字volatile。尽管volatile 在下章会被很仔细的讨论,用在此处以确保running的值在下面的循环中每次都得到验证。
while (running) {
click++;
}
如果不用volatile,Java可以自由的优化循环:running的值被存在CPU的一个寄存器中,
每次重复不一定需要复检。volatile的运用阻止了该优化,告知Java running可以改变,改变
方式并不以直接代码形式显示。
Java知多少(61)线程优先级的更多相关文章
- Java知多少(56)线程模型
Java运行系统在很多方面依赖于线程,所有的类库设计都考虑到多线程.实际上,Java使用线程来使整个环境异步.这有利于通过防止CPU循环的浪费来减少无效部分. 为更好的理解多线程环境的优势可以将它与它 ...
- Java知多少(57)主线程
当Java程序启动时,一个线程立刻运行,该线程通常叫做程序的主线程(main thread),因为它是程序开始时就执行的.主线程的重要性体现在两方面: 它是产生其他子线程的线程: 通常它必须最后完成执 ...
- 了解Java线程优先级,更要知道对应操作系统的优先级,不然会踩坑
Java 多线程系列第 6 篇. 这篇我们来看看 Java 线程的优先级. Java 线程优先级 Thread 类中,使用如下属性来代表优先级. private int priority; 我们可以通 ...
- Java多线程系列--“基础篇”10之 线程优先级和守护线程
概要 本章,会对守护线程和线程优先级进行介绍.涉及到的内容包括:1. 线程优先级的介绍2. 线程优先级的示例3. 守护线程的示例 转载请注明出处:http://www.cnblogs.com/skyw ...
- [改善Java代码]线程优先级只使用三个等级
线程的优先级(priority)决定了线程获得CPU运行的机会,优先级越高获得的运行机会越大,优先级越低获得的机会越小.Java的线程有10个级别(准确的说是11个级别,级别为0的线程是JVM,应用程 ...
- JAVA并发,线程优先级
package com.xt.thinks21_2; import java.util.concurrent.ExecutorService; import java.util.concurrent. ...
- Java中线程的使用 (2)-多线程、线程优先级、线程睡眠、让步、阻塞
Java中线程的使用 (2)-多线程.线程优先级.线程睡眠.让步.阻塞 (一)多线程使用方法 说明:创建每个新的线程,一定要记得启动每个新的线程(调用.start()方法) class Xc3 ext ...
- java线程优先级
java的线程优先级分为1-10 这10个等级 1为最强,最优先 10为最弱 如果大于10或者小于1则会抛异常 源代码为: public final void setPriority(int newP ...
- Java多线程(十)——线程优先级和守护线程
一.线程优先级的介绍 java 中的线程优先级的范围是1-10,默认的优先级是5.“高优先级线程”会优先于“低优先级线程”执行. java 中有两种线程:用户线程和守护线程.可以通过isDaemon( ...
随机推荐
- supervisor 管理 celery
安装supervisor [root@ipv6-api ~]# pip3 install supervisor 生成配置文件 [root@ipv6-api ~]#echo_supervisord_c ...
- NOIP2013 花匠解题报告
//<NOIP2013> 花匠 /* 最优子结构性质,可以用动规.注意到存在30%的变态数据(1 ≤ n ≤ 100,000, 0 ≤ h_i ≤1,000,000),因此应当找到线性的算 ...
- CentOS 与 Ubuntu 使用命令搭建 LAMP 环境
LAMP指的Linux操作系统 + Apache服务器 + MariaDB/MySQL数据库软件 + PHP开发语言的第一个字母. ==================CentOS LAMP===== ...
- DIY自己的AllocateHWnd函数
Classes单元的AllocateHWnd函数是需要传入一个处理消息的类的方法的作为参数的,原型: function AllocateHWnd(Method: TWndMethod): HWND; ...
- 奇怪吸引子---LuChen
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- Go语言之高级篇Beego框架之爬虫项目实战
一.爬虫项目 1.爬虫基础 a.网页上面会有相同的数据 b.去重处理 布隆过滤器哈希存储 c.标签匹配: 正则表达式beautiful soup或lxml这种标签提取库 d.动态内容 phantomj ...
- GitHub超全机器学习工程师成长路线图,开源两日收获3700+Star!【转】
作者 | 琥珀 出品 | AI科技大本营(ID:rgznai100) 近日,一个在 GitHub 上开源即收获了 3700+ Star 的项目,引起了营长的注意.据介绍,该项目以 TensorFlow ...
- qt不能调试
在F5执行qt的调试时,提示:unknown debugger type "No engine" 需要下载debug调试工具,win7的下载位于:https://www.micro ...
- WPF背景图
方法一:xaml中:<控件> <控件.Background><ImageBrush ImageSource="/程序集;component/images/xx ...
- ubuntu16 64位 编译64位程序和32位程序
安装了ubuntu16 64位的系统,想在该环境下用gcc编译64位和32位的程序 默认已经安装了64位环境的gcc 1. 首先确认安装的环境是不是64位的 cocoa@cocoaUKlyn:~/De ...