`
epy
  • 浏览: 324566 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java多线程优先级的一些测试

阅读更多

 Java的每个线程都有一个优先级,当有多个线程处于就绪状态时,线程调度程序根据线程的优先级调度线程运行。
可以用下面方法设置和返回线程的优先级。
  public final void setPriority(int newPriority) 设置线程的优先级。
  public final int getPriority() 返回线程的优先级。
  newPriority为线程的优先级,其取值为1到10之间的整数,也可以使用Thread类定义的常量来设置线程的优先级,这些常量分别为:Thread.MIN_PRIORITY、Thread.NORM_PRIORITY、Thread.MAX_PRIORITY,它们分别对应于线程优先级的1、5和10,数值越大优先级越高。当创建Java线程时,如果没有指定它的优先级,则它从创建该线程那里继承优先级。

 

不过设置优先级后有没有效果呢?

有人讲有,有人讲没有。如果是底层操作系统不支持优先级,那估计JVM也没办法;通常的Window系统和Linux系统还是支持优先级的,设置后是不是有效果呢?光是理论分析,难以有直观的认识,还是做个实验来看看吧。

 

实验环境

操作系统是Windows XP SP3,CPU是AMD FX-5000四核 2.21GHz,内存2G。

 

线程类

import java.util.Random;

public class HardJob extends Thread {
    private volatile boolean running = true;
    
    public HardJob(String name) {
        super(name);
    }
    
    public void shutdown() {
        running = false;
    }
    
    public void run() {
        double result = 0;
        int cnt = 0;
        Random randGen = new Random();
        
        System.out.println(this.getName() + "(Priority " + this.getPriority() + "), begin to run.");
        while (running) {
            result += Math.sin(randGen.nextDouble() * 2 * Math.PI);
            cnt++;
        }
        System.out.println(this.getName() + "(Priority " + this.getPriority() + "), run " + cnt + " times.");
    }
}

 

 线程启动后,会不断执行正弦运算,直到被shutdown,最后输出执行的运算次数。

 

主测试类

public class HardJobTest {
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        //给主线程设置最高优先级,以保证shutdown命令能按时发出去。
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        
        //创建一个线程数组
        HardJob arrJob[] = new HardJob[2];
        for (int i = 0; i < arrJob.length; i++) {
            arrJob[i] = new HardJob("job" + String.valueOf(i + 1));
            
            //给各个线程分别设置优先级,可根据需要进行修改。
            arrJob[i].setPriority(i + 2);
        }
        
        for (int i = 0; i < arrJob.length; i++) {
            arrJob[i].start();
        }
        
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        for (int i = 0; i < arrJob.length; i++) {
            arrJob[i].shutdown();
        }
        
    }
    
}

 
测试程序刚开始启动若干个子线程,设置优先级,然后主线程休眠10秒钟,醒来后,关掉所有子线程;子线程接到指令后停止循环,输出执行的运算次数。

 

测试情况

1. 只启动一个子线程,优先级分别设置为1, 5, 10。

三次的测试结果分别为:

job1(Priority 1), run 46754702 times.

job1(Priority 5), run 46538646 times.

job1(Priority 10), run 47020496 times.

 

三次执行次数差不多,都是四千多万次;CPU使用率为25-27%,我的机器为四核CPU,可以认为这个线程占用了一个CPU。

 

2. 启动两个子线程

优先级都设置为5,测试结果为:

job1(Priority 5), run 46572545 times.
job2(Priority 5), run 46625719 times.

CPU使用率为50-52%。

 

优先级分别设置为1和10,测试结果为:

job2(Priority 10), run 46704322 times.
job1(Priority 1), run 46303699 times.

CPU使用率为50-52%。

 

  执行次数差不多,都是四千多万次,可以认为这两个线程各占用了一个CPU。

 

3. 启动四个子线程

优先级都设置为5,测试结果为:

job3(Priority 5), run 46512541 times.
job1(Priority 5), run 46630886 times.
job2(Priority 5), run 46442715 times.
job4(Priority 5), run 46913636 times.

CPU使用率为100%。

 

优先级分别设置为2、4、6、8,测试结果为:

job3(Priority 6), run 45987741 times.
job1(Priority 2), run 43118444 times.
job4(Priority 8), run 46514473 times.
job2(Priority 4), run 45445105 times.

CPU使用率为100%。

 

  执行次数差不多,都是四千多万次,优先级为8的线程比优先级为2的线程略微多执行了些。

  从结果上来看,可以认为这四个线程各占用了一个CPU。

 

4. 启动八个子线程

优先级都设置为5,测试结果为:

job1(Priority 5), run 23397717 times.
job3(Priority 5), run 23019800 times.
job5(Priority 5), run 23014664 times.
job8(Priority 5), run 23414866 times.
job2(Priority 5), run 22976901 times.
job6(Priority 5), run 23310006 times.
job4(Priority 5), run 23506321 times.
job7(Priority 5), run 23073406 times.

CPU使用率为100%。

执行次数只有之前的一半左右,可以近似认为每两个线程平分一个CPU。

 

优先级分别设置为2到9,测试结果为:

job7(Priority 8), run 46729368 times.
job8(Priority 9), run 47380536 times.
job6(Priority 7), run 46659873 times.
job4(Priority 5), run 19932864 times.
job5(Priority 6), run 24848567 times.
job2(Priority 3), run 526607 times.
job3(Priority 4), run 185692 times.
job1(Priority 2), run 230829 times.

CPU使用率为100%。

优先级为2、3、4的线程只执行了不到六十万次运算;
优先级为5、6的线程执行了约两千万次,
优先级为7、8、9的线程都执行了四千多万次,属于满负荷运行;

看来线程优先级还是有用的。

 

5. 启动16个子线程

优先级分别设置为2到9,测试结果为:

job8(Priority 9), run 47253075 times.
job6(Priority 7), run 23552148 times.
job7(Priority 8), run 23220591 times.
job15(Priority 8), run 21735566 times.
job14(Priority 7), run 23148908 times.
job16(Priority 9), run 46963640 times.
job5(Priority 6), run 206322 times.
job4(Priority 5), run 174672 times.
job2(Priority 3), run 282183 times.
job13(Priority 6), run 0 times.
job11(Priority 4), run 0 times.
job3(Priority 4), run 547 times.
job9(Priority 2), run 0 times.
job12(Priority 5), run 0 times.
job10(Priority 3), run 0 times.
job1(Priority 2), run 233635 times.

CPU使用率为100%。

优先级为9的线程执行了四千多万次,属于满负荷运行;

优先级为7、8的线程执行了二千多万次;

其他线程执行了不到三十万次。 

小结

从实验结果来看,如果CPU有空闲,即使是低优先级的线程,也可以得到足够的执行时间,接近满负荷执行。

如果CPU比较繁忙,优先级的作用就体现出来了,优先级高的线程能得到比较多的执行时间,优先级比较低的线程也能得到一些执行时间,但会少一些;CPU越繁忙,差异通常越明显。

 

分享到:
评论

相关推荐

    Java线程赛马优先级示例.rar

    Java线程赛马优先级示例,左侧的是高优先级,右侧的是低优先级。点击“Start”开始测试。

    JAVA高级程序设计测试题含答案.docx

    currentThread() 第9题 【单选题】【2.00分】【概念理解】 下面关于线程优先级的说法中,正确的是 [单选题] * A. 线程的优先级是不能改变的 B. 线程的优先级是在创建线程时设置的 C. 在创建线程后的任何时间都可以...

    Java开发技术大全(500个源代码).

    demoPri.java 调用上面这个类设置线程优先级示例 myThread.java 自己定义的一个Thread的子类 mutexThread.java 一个能管理临界区的线程类 demoMutex.java 使用上面这个类来演示线程的互斥 commSource.java 一个...

    Java高级程序设计测试含答案.docx

    () [单选题] * A.wait()(正确答案) B.sleep() C.yield() D.currentThread() 下面关于线程优先级的说法中,正确的是() [单选题] * A.线程的优先级是不能改变的 B.线程的优先级是在创建线程时设置的 C.在...

    Java 7并发编程实战手册

    全书通过60多个简单而非常有效的实例,帮助读者快速掌握Java 7多线程应用程序的开发技术。学习完本书,你可以将这些开发技术直接应用到自己的应用程序中。 《Java 7并发编程实战手册》适合具有一定Java编程基础的...

    Java测试题2答案

    《Java测试题2》 &lt;br&gt;一、 选择 1.欲构造ArrayList类的一个实例,此类继承了List接口,下列哪个方法是正确的 ? B A ArrayList myList=new Object(); B List myList=new ArrayList(); C ...

    java 编程入门思考

    1.9 多线程 1.10 永久性 1.11 Java和因特网 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失 1.12.2 阶段0:拟出一个计划 1.12.3 阶段...

    java联想(中文)

    1.9 多线程 1.10 永久性 1.11 Java和因特网 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失 1.12.2 阶段0:拟出一个计划 1.12.3 阶段...

    Java初学者入门教学

    1.9 多线程 1.10 永久性 1.11 Java和因特网 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失 1.12.2 阶段0:拟出一个计划 1.12.3 阶段...

    Java并发编程(学习笔记).xmind

    (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 (2)建模简单:通过使用线程可以讲复杂并且异步的工作流进一步分解成一组简单并且同步的工作流,每个工作流在一个单独的线程...

    JAVA基础课程讲义

    JAVA中如何实现多线程(重点!!) 168 通过继承Thread类实现多线程 168 通过Runnable接口实现多线程 169 线程状态和sleep/yield/join/stop/destroy方法 170 新生状态 170 就绪状态 170 运行状态 170 死亡状态 170 ...

    Thinking in Java 中文第四版+习题答案

    1.9 多线程 1.10 永久性 1.11 Java和因特网 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失 1.12.2 阶段0:拟出一个计划 1.12.3 阶段...

    JAVA_Thinking in Java

    1.9 多线程 1.10 永久性 1.11 Java和因特网 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失 1.12.2 阶段0:拟出一个计划 1.12.3 阶段...

    Thinking in Java简体中文(全)

    1.9 多线程 1.10 永久性 1.11 Java和因特网 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失 1.12.2 阶段0:拟出一个计划 1.12.3 阶段...

    实战Java高并发程序设计(第2版)PPT模板.pptx

    3.1多线程的团队协作:同步控制 3.2线程复用:线程池 3.3不要重复发明轮子:jdk的并发容器 3.4使用jmh进行性能测试 3.2线程复用:线程池 3.3不要重复发明轮子:JDK的并发容器 3.4使用JMH进行性能测试 实战Java高并发...

    java8源码-JavaSE-Code:JavaSE的代码练习与学习笔记总结

    [Java多线程核心编程技术] 书籍笔记 第一章:Java多线程技能 线程是进程中的子任务 interrupted与isInterrupted的区别: interrupted是Thread类的静态方法,里面调用了isTnterrupted方法[currentThread().isInterrupted...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    6.1.4 线程的优先级 114 6.1.5 中断线程 115 6.1.6 线程组 116 6.1.7 处理未被捕获的异常 117 6.1.8 守护线程 117 6.2 同步与锁 118 6.2.1 synchronized和同步 118 6.2.2 锁对象 120 6.2.3 Condition对象 ...

Global site tag (gtag.js) - Google Analytics