并发基础(三) java线程优先级
在不同的JVM中(JVM也算是一个操作系统),有着不同的CPU调度算法,对于大部分的JVM来说,优先级也是调度算法中的一个参数。所以,线程优先级在一定程度上,对线程的调度执行顺序有所影响,但不能用于保证线程的执行顺序,因为优先级仅仅是其中一个参数而已,其他参数还可能有线程的等待时间、执行时间等。而且操作系统也可抗能可以完全不用理会JAVA线程对于优先级的设定。
线程优先级的范围一般是1~10,默认是5,但也有的JVM不是这个范围。所以,一般也尽量不要设置优先级为数字,可以使用Thread类的3个静态字段,
static int MAX_PRIORITY : 线程可以具有的最高优先级。
static int MIN_PRIORITY : 线程可以具有的最低优先级。
static int NORM_PRIORITY : 分配给线程的默认优先级。
同时。对于需要较多CPU时间的线程需要设置较低的优先级,这样可以确保处理器不会被独占。
下面是在windows下测试的例子。一直在思考怎么设计,才能用简单明了的例子来证明优先级对线程的执行顺序有影响,最后为了严谨,还是不得不用到线程锁,可能对初学者来说,有点难理解。
不过思路是很清晰的:就是如何让10个线程一起同时并发。首先让创建的10个线程依次进入对象锁的池中等待,然后当10个线程创建完后,main线程(主线程)同时唤醒这10个线程,于是10个线程同时一起并发竞争CPU,只计算5次,看看线程的结束的先后顺序。(注意:之所以线程的执行次数限制在5次,而不是无限,是因为会发生线程饥饿,高优先级线程占用着CPU,导致低优先级的线程无法被调度!!)
public class Test2 {
//obj对象 用于作为对象锁
static String obj="";
public static void main(String[] args) {
//创建十个不同优先级的线程
for(int i=1;i<10;i++){
Thread t = new Thread(new Task(),"Thread_"+i);
t.setPriority(i);
//线程启动,进入就绪队列
t.start();
try {
//当前线程--main线程 休眠100毫秒,确保线程t已经创建完成,并能运行到等待获取锁处
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (obj) {
//main线程获取对象锁后,唤醒等待在该对象池上的所有线程--就是上面创建的10个线程
obj.notifyAll();
}
}
}
//实现 Runnable接口
class Task implements Runnable{
@Override
public void run() {
synchronized (Test2.obj) {
try {
//在对象Test2.obj上等待,
Test2.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//线程唤醒后,执行下面的代码
int count=0;
//计算5次,不能是while(true),不限制执行次数,否则会发生线程饥饿
while(count<5){
count++;
System.out.println(Thread.currentThread().getName());
//每次计算完后,让出CPU,重新进入就绪队列,与其他线程一起竞争CPU
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+"结束");
}
}
测试结果:
从结果可以看出,虽然线程的结束顺序不是完全按照优先级高低,但也基本是优先级高的线程结束的较快,被CPU调度的概率越大。
Thread_9
Thread_5
Thread_6
Thread_8
Thread_7
Thread_9
Thread_8
Thread_7
Thread_9
Thread_8
Thread_9
Thread_7
Thread_9
Thread_7
Thread_8
Thread_9结束
Thread_8
Thread_7
Thread_8结束
Thread_7结束
Thread_4
Thread_5
Thread_6
Thread_3
Thread_5
Thread_6
Thread_5
Thread_6
Thread_5
Thread_6
Thread_5结束
Thread_6结束
Thread_4
Thread_2
Thread_3
Thread_4
Thread_1
Thread_3
Thread_4
Thread_3
Thread_4
Thread_3
Thread_4结束
Thread_3结束
Thread_2
Thread_1
Thread_2
Thread_1
Thread_2
Thread_1
Thread_2
Thread_1
Thread_1结束
Thread_2结束
并发基础(三) java线程优先级的更多相关文章
- 【Java并发基础】Java线程的生命周期
前言 线程是操作系统中的一个概念,支持多线程的语言都是对OS中的线程进行了封装.要学好线程,就要搞清除它的生命周期,也就是生命周期各个节点的状态转换机制.不同的开发语言对操作系统中的线程进行了不同的封 ...
- 了解Java线程优先级,更要知道对应操作系统的优先级,不然会踩坑
Java 多线程系列第 6 篇. 这篇我们来看看 Java 线程的优先级. Java 线程优先级 Thread 类中,使用如下属性来代表优先级. private int priority; 我们可以通 ...
- 关于CPU核心,线程,进程,并发,并行,及java线程之间的关系
前言:作为一个转行java的小白,一直搞不清楚java中的多线程.于是来梳理一下关于CPU核心,线程,进程,并发,并行,及java线程之间的关系, 1.CPU角度来看: 我们以Intel的Core i ...
- Java并发(三)线程池原理
Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池能够带来3个好处. 1. 降低资源消耗.通过重复利用已创建的线程降低线程 ...
- Java - 线程优先级和守护线程
Java多线程系列--“基础篇”10之 线程优先级和守护线程 概要 本章,会对守护线程和线程优先级进行介绍.涉及到的内容包括:1. 线程优先级的介绍2. 线程优先级的示例3. 守护线程的示例 转载请注 ...
- Java并发指南1:并发基础与Java多线程
本文转载自互联网,侵删 什么是并发 在过去单CPU时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是 ...
- 【Java并发基础】Java内存模型解决有序性和可见性
前言 解决并发编程中的可见性和有序性问题最直接的方法就是禁用CPU缓存和编译器的优化.但是,禁用这两者又会影响程序性能.于是我们要做的是按需禁用CPU缓存和编译器的优化. 如何按需禁用CPU缓存和编译 ...
- java线程优先级
java的线程优先级分为1-10 这10个等级 1为最强,最优先 10为最弱 如果大于10或者小于1则会抛异常 源代码为: public final void setPriority(int newP ...
- 【java基础】Java运算符优先级
Java运算符优先级 序列号 符号 名称 结合性(与操作数) 目数 说明 1 . 点 从左到右 双目 ( ) 圆括号 从左到右 [ ] 方括号 从左到右 2 + 正号 从右到左 单目 - 负号 ...
随机推荐
- Linux环境下 多线程下载 (Python 实现版)
本文是多年前学习编程时参照一个网友程序的基础之上改写的, 采用Python语音编写, 多线程下载功能, 可以有效提高Linux下原有下载工具中的一些不足,以下给出具体代码. #!/usr/bin/py ...
- 各种CTF的WP
http://l-team.org/archives/43.html PlaidCTF-2014-twenty/mtpox/doge_stege-Writeup http://l-team.org/a ...
- 关于bfs与dfs的标记区别
回顾一下dfs与bfs的使用,由于二者都需要避免走重复的路,所以二者都需要对数组进行标记 而二者的标记操作的不同点是 dfs会对数组的标记进行清除(包含两种标记,一种对形参变量的标记,这个清除是返回上 ...
- DataFrame 列运算
import pandas as pd import StringIO table_buffer = StringIO.StringIO('''a b 2007-01-08 0.786667 270 ...
- ioctl命令
_IO._IOR._IOW._IOWR 宏的使用说明 驱动程序中 ioctl 函数传递的变量 cmd 是应用程序向驱动程序请求处理的命令.cmd 除了用于区别不同命令的数值,还可包含有助于处理的几种 ...
- day30 python学习 struct模块和 subprocess 模块
import subprocess import struct aa=input('>>') obj=subprocess.Popen(aa,shell=True,#aa代表的是读取字符串 ...
- dns over https 简单测试(docker 运行)
dns over https 已经成为了标准了,给予我们的dns 解析添加了安全的支持 测试项目使用docker && docker-compose 运行 一张参考图 环境准备 d ...
- dup and dup2的剖析
转:http://www.cnblogs.com/sdphome/archive/2011/04/30/2033381.html dup和dup2都可用来复制一个现存的文件描写叙述符,使两个文件描写叙 ...
- 应用解决告诉你什么时候该用ajax
第一.请求的提交是为了页面数据的显示,这时候用户一般不希望看到页面的刷新,是使用AJAX的一个最佳时候. 第二.如果请求提交后,用户能从页面感觉到提交结果,这时候,也最好不要有页面刷新,推荐使用AJA ...
- JUC集合之 LinkedBlockingDeque
LinkedBlockingDeque介绍 LinkedBlockingDeque是双向链表实现的双向并发阻塞队列.该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入 ...