七. 多线程编程7.线程优先级

线程优先级被线程调度用来判定何时每个线程允许运行。理论上,优先级高的线程比优先级低的线程获得更多的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 quqiongyule2.com ) {
            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可以改变,改变
方式并不以直接代码形式显示。

时间: 2024-08-05 07:07:11

七. 多线程编程7.线程优先级的相关文章

七. 多线程编程9.线程间通信

上述例题无条件的阻塞了其他线程异步访问某个方法.Java对象中隐式管程的应用是很强大的,但是你可以通过进程间通信达到更微妙的境界.这在Java中是尤为简单的. 像前面所讨论过的,多线程通过把任务分成离散的和合乎逻辑的单元代替了事件循环程序.线程还有第二优点:它远离了轮询.轮询通常由重复监测条件的循环实现.一旦条件成立,就要采取适当的行动.这浪费了CPU时间.举例来说,考虑经典的序列问题,当一个线程正在产生数据而另一个程序正在消费它.为使问题变得更有趣,假设数据产生器必须等待消费者完成工作才能产生

七. 多线程编程8.线程同步

当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用.达到此目的的过程叫做同步(synchronization).像你所看到的,Java为此提供了独特的,语言水平上的支持. 同步的关键是管程(也叫信号量semaphore)的概念.管程是一个互斥独占锁定的对象,或称互斥体(mutex).在给定的时间,仅有一个线程可以获得管程.当一个线程需要锁定,它必须进入管程.所有其他的试图进入已经锁定的管程的线程必须挂起直到第一个线程退出管程.这些其他的线程被称为等待管程.一个

七. 多线程编程11.线程的挂起、恢复和终止

有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线程机制在Java 2和早期版本中有所不同.尽管你运用Java 2的途径编写代码,你仍需了解这些操作在早期Java环境下是如何完成的.例如,你也许需要更新或维护老的代码.你也需要了解为什么Java 2会有这样的变化.因为这些原因,下面内容描述了执行线程控制的原始方法,接着是Java 2的方法. Jav

.NET面试题解析(07)-多线程编程与线程同步

系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等,本文只是从常见面试题的角度(也是开发过程中常用)去深入浅出线程相关的知识.如果想要系统的学习多线程,没有捷径的,也不要偷懒,还是去看专业书籍的比较好. 常见面试题目: 1. 描述线程与进程的区别? 2. 为什么GUI不支持跨线程访问控件?一般如何解决这个问题? 3. 简述后台线程和前台线程的区别? 4. 说说常

Android多线程编程之线程池学习篇(一)

Android多线程编程之线程池学习篇(一) 一.前言 Android应用开发中多线程编程应用比较广泛,而应用比较多的是ThreadPoolExecutor,AsyncTask,IntentService,HandlerThread,AsyncTaskLoader等,为了更详细的分析每一种实现方式,将单独成篇分析.后续篇章中可能涉及到线程池的知识,特此本篇分析为何使用线程池,如何使用线程池以及线程池的使用原理. 二.Thread Pool基础 进程代表一个运行中的程序,一个运行中的Android

C#多线程编程实例 线程与窗体交互

代码: public partial class Form1 : Form { //声明线程数组 Thread[] workThreads = new Thread[10]; public Form1() { InitializeComponent(); } //此委托允许异步的调用为Listbox添加Item delegate void AddItemCallback(string text); //这种方法演示如何在线程安全的模式下调用Windows窗体上的控件. private void

vc 基于对话框多线程编程实例——线程之间的通信

 vc基于对话框多线程编程实例--线程之间的通信 实例: vc 基于对话框多线程编程实例--线程之间的通信,码迷,mamicode.com

Linux程序设计学习笔记----多线程编程之线程同步之条件变量

转载请注明出处:http://blog.csdn.net/suool/article/details/38582521. 基本概念与原理 互斥锁能够解决资源的互斥访问,但是在某些情况下,互斥并不能解决问题,比如两个线程需 要互斥的处理各自的操作,但是一个线程的操作仅仅存在一种条件成立的情况下执行,一旦错过不可再重现,由于线程间相互争夺cpu资源,因此在条件成立的时候,该线程不一定争夺到cpu而错过,导致永远得不到执行..... 因此需要某个机制来解决此问题,更重要的是,线程仅仅只有一种情况需要执

Java多线程编程之限制优先级

限制线程优先级和调度 作者:兄弟连 Java 线程模型涉及可以动态更改的线程优先级.本质上,线程的优先级是从 1 到 10 之间的一个数字,数字越大表明任务越紧急.JVM 标准首先调用优先级较高的线程,然后才调用优先级较低的线程.但是,该标准对具有相同优先级的线程的处理是随机的.如何处理这些线程取决于基层的操作系统策略.在某些情况下,优先级相同的线程分时运行:在另一些情况下,线程将一直运行到结束.请记住,Java 支持 10 个优先级,基层操作系统支持的优先级可能要少得多,这样会造成一些混乱.因