线程优先级
现代操作系统基本采用时分的形式调度运行的线程,操作系统会分出一个个时间片,线程会分配到若干时间片,当线程的时间片用完了就会发生线程调度,并等待着下次分配。线程分配到的时间片多少也就决定了线程使用处理器资源的多少,而线程优先级就是决定线程需要多或者少分配一些处理器资源的线程属性。
在Java线程中,通过一个整型成员变量priority来控制优先级,优先级的范围从1~10,在线程构建的时候可以通过setPriority(int)方法来修改优先级,默认优先级是5,优先级高的线程分配时间片的数量要多于优先级低的线程。设置线程优先级时,针对频繁阻塞(休眠或者I/O操作)的线程需要设置较高优先级,而偏重计算(需要较多CPU时间或者偏运算)的线程则设置较低的优先级,确保处理器不会被独占。在不同的JVM以及操作系统上,线程规划会存在差异, 有些操作系统甚至会忽略对线程优先级的设定。
我们需要值得注意的是 程序正确性不能依赖线程的优先级高低 线程的优先级只是优先级高的线程分配时间片的数量要多于优先级低的线程。
下面我们用一段代码来解释:
在代码中我们创建10个线程,5个优先级别最低,5个级别最高。线程中的jobCount属性作为资源的分配假象。由于for循环创建的线程有先后,所以我们在run方法中使用yield让先创建完的线程进入就绪状态,等到所有线程创建结束了,notStart再设置为false,进入下一个循环,让10个线程同时开始竞争
public class Priority {
private static volatile boolean notStart = true;
private static volatile boolean notEnd = true;
public static void main(String[] args) throws Exception {
List<Job> jobs = new ArrayList<Job>();
for (int i = 0; i <10 ; i++) {
int priority = i < 5 ?Thread.MIN_PRIORITY:Thread.MAX_PRIORITY;
Job job = new Job(priority);
jobs.add(job);
Thread thread = new Thread(job,"Thread:"+i);
thread.setPriority(priority);
thread.start();
}
notStart=false;
TimeUnit.SECONDS.sleep(10);
notEnd=false;
for (Job job: jobs) {
System.out.println("Job Priority : "+job.priority+"Count : "+job.jobCount);
}
}
static class Job implements Runnable{
private int priority;
private long jobCount;
public Job(int priority){
this.priority=priority;
}
@Override
public void run() {
while(notStart){
Thread.yield();
}
while(notEnd){
Thread.yield();
jobCount++;
}
}
}
}
运行结果如下:
从输出可以看到线程优先级没有生效,优先级1和优先级10的Job计数的结果非常相近, 没有明显差距。这表示程序正确性不能依赖线程的优先级高低
所以,Thread的优先级并不可靠,我们需要自己用代码实现他的优先级
参考文献:《Java并发编程的艺术》
好了,这次的文章就到这里,喜欢的同学可以点赞收藏,遇到问题,可以评论,或者留言,我一定会第一时间给到回馈,感谢观看!!
注:本文为本人学习时心得分享,有讲错或者需要改正的地方,请指正,我会虚心接受