zoukankan      html  css  js  c++  java
  • [改善Java代码]线程优先级只使用三个等级

    线程的优先级(priority)决定了线程获得CPU运行的机会,优先级越高获得的运行机会越大,优先级越低获得的机会越小.Java的线程有10个级别(准确的说是11个级别,级别为0的线程是JVM,应用程序不能设置该级别)

    那是不是级别为10的线程肯定比级别为9的线程优先运行呢?

    看代码:

     1 public class Client {
     2     public static void main(String[] args){
     3         //启动20个不同优先级的线程
     4         for (int i = 0; i < 20; i++) {
     5             new TestThread().start(i % 10 + 1);
     6         }
     7 
     8     }
     9 }
    10 
    11 class TestThread implements Runnable {
    12     //启动线程
    13     public void start(int _priority) {
    14         Thread t = new Thread(this);
    15         //设置线程优先级
    16         t.setPriority(_priority);
    17         t.start();
    18     }
    19 
    20     @Override
    21     public void run() {
    22         //消耗CPU的计算,性能差的机器,请修改循环限制
    23         for (int i = 0; i < 100000; i++) {
    24             Math.hypot(Math.pow(924526789,i),Math.cos(i));
    25         }
    26         //输出线程优先级
    27         System.out.println("Priority:" + Thread.currentThread().getPriority());
    28 
    29     }
    30 }

    该多线程类实现了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的原则,但是也不能完全保证.

  • 相关阅读:
    一些博客
    【iOS】得到当前年、月、周的第一天和最后一天
    iOS学习路线
    UI开发--响应者链条
    通知中心 NSNotificationCenter
    UITableView的编辑(插入、删除、移动)
    FMDatabaseQueue 如何保证线程安全
    理解 dispatch_get_specific
    instancetype
    【转】手把手教你ARC——iOS/Mac开发ARC入门和使用
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/5623826.html
Copyright © 2011-2022 走看看