分享
 
 
 

Java Thread Programming 1.6 - Thread Prioritization

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

System Thread Priorities—JDK 1.2

Priority

Thread Name

5

main

8

Finalizer

10

Reference Handler

5

Signal dispatcher

5

AWT-Windows

6

AWT-EventQueue-0

5

SunToolkit.PostEventQueue-0

4

Screen Updater

A notable change in JDK 1.2 is that the priority of the Finalizer thread was increased from 1 to 8 to help ensure that the garbage collector gets more of a chance to run and free up memory.

Jdk1.2中Finalizer线程的优先级从1升高到8,确保垃圾收集器能及时回收资源释放内存

When assigning priorities to your threads, you should consider the relative priorities of the system threads to be sure your threads don’t overwhelm their operations. By default, when a new Thread is constructed, it runs at the same priority as the thread that constructed it. Most new threads are constructed directly or indirectly by the main thread and will therefore run at a priority of 5. This works well under many scenarios, but there are times when you will want to raise or lower a thread’s priority.

子线程的优先级和父线程的优先级相同,大部分线程从main线程创建,所以优先级为5

There are three public static final int member variables of Thread that indicate the range of priority values that can be passed to setPriority().

Thread.MAX_PRIORITY

Thread.MIN_PRIORITY

Thread.NORM_PRIORITY

Thread类中有三个静态优先级变量

Thread.MAX_PRIORITY,最高优先级,通常为10

Thread.MIN_PRIORITY,最低优先级,通常为1

Thread.NORM_PRIORITY,一般优先级,通常为5

getPriority()

The getPriority() method of Thread returns an int representing the current priority of the thread. Generally, a thread’s priority does not change over its lifetime, but it can.

getPriority()返回线程的当前优先级,通常线程的优先级在其生命周期中不会变,但可以变

setPriority()

The setPriority() method of Thread takes an int as a parameter indicating the new priority for the thread. The setPriority() method can be invoked either before the thread is started or once it is running. Some VMs might allow you to change the priority of the system threads, but this is not recommended—even if it is permitted.

setPriority()设置线程新的优先级,可以在线程开始前调用,也可以在线程运行中调用,有些虚拟机允许改变系统线程的优先级,但我们不推荐这么做

Calls to setPriority can throw a SecurityException if the calling thread is not permitted to make the priority change. This will happen only if there is a SecurityManager installed and it rejects the change request. By default, applications do not have a SecurityManager.

如果不允许线程优先级改变,调用setPriority()方法时会抛出SecurityException异常,当安装了SecurityManager时,可能会出现这种情况

An IllegalArgumentException will be thrown if the specified priority is greater than Thread.MAX_PRIORITY or less than Thread.MIN_PRIORITY.allowed for the thread group. For example, in this code fragment

Thread t = //...

ThreadGroup tg = t.getThreadGroup();

int groupMax = tg.getMaxPriority();

the maximum value for the thread priority of thread t is groupMax. Usually, this is the same as Thread.MAX_PRIORITY. When groupMax is less than Thread.MAX_PRIORITY, calls to setPriority() still work, but will silently reduce the value passed to groupMax. If groupMax is 6 and setPriority(9) is called, the code will run as if setPriority(6) was called instead. See Chapter 10, “Thread Groups,” for more on ThreadGroup.

如果将线程优先级设置在线程组的Thread.MAX_PRIORITY,和Thread.MIN_PRIORITY之外,会抛出IllegalArgumentException异常。线程组允许的最大优先级和Thread.MAXPRIORITY可能会不一致,如果线程组最大优先级为6,而将线程优先级设置为9,那么代码执行的结果和setPriority(6)一样。

Thread States

State

Blocked

Interrupted

Discription

Running

Current running on the processor

Ready to run

Waiting for the processor

Sleeping

Will move to “ready to run” state

after a certain amount of time has eclipsed or after being interrupted

Waiting

Will move to “ready to run” state

after being notice, after timeout or after being interrupted

Blocked on I/O

Will move to “ready to run” after I/O

Condition changes(for example,a byte of date is read)

Blocked on sync

Will move to “ready to run” when lock is acquired(passes synchronized statement)

Threads can be blocked in one of four states. When a thread executes Thread.sleep(), it blocks until the specified number of milliseconds passes or until it is interrupted by another thread. When a thread encounters a wait() statement (see Chapter 8, “Inter-thread Communication,” for more on the wait/notify mechanism), it blocks until it is notified, interrupted, or the specified number of milliseconds elapses (if a timeout was specified).

There are many ways a thread can block waiting on different I/O methods. One common way is the read() method of InputStream. This method blocks until a byte of data is read from the stream. It can block indefinitely, and no timeout can be specified.

A thread can also block waiting to acquire exclusive access to an object’s lock. The synchronized statement and synchronized method modifier (see Chapter 7, “Concurrent Access to Objects and Variables,” for more on synchronization) are used to control concurrent access by more than one thread to a section of code. A thread will block on synchronized until it gets the specified lock. It can block indefinitely, and no timeout can be specified.

有四种方式线程会被阻塞:

1、调用Thread.sleep(),时间完成、被其他线程打断时改变状态

2、wait/notify时线程遇到wait()时,当被notified,被别的线程打断,或者特定时间结束时改变状态

3、I/O阻塞

4、锁阻塞,同步锁时,线程得到此锁时改变状态

Notice that not all blocked states are interruptible. When a thread is blocked waiting to read a byte of data from an InputStream, it will not respond to interrupts (see Chapter 15, “Breaking Out of a Blocked I/O State,” for some techniques for dealing with this). When a thread is blocked waiting to get the lock required by a synchronized statement, it also will not respond to interrupt requests (see Chapter 17, “BooleanLock Utility,” for a technique that deals with long waits for locks).

不是所有的阻塞状态都可以被打断的,I/O阻塞和锁阻塞是不能被中断的

Thread.yield()

To help ensure that other threads in the VM get a turn to run on the processor, a thread can voluntarily give up its turn early. If a thread invokes the static method Thread.yield(), the thread scheduler will swap it off the processor and allow another thread to run. It is likely (but not guaranteed) that only threads having a priority equal to or greater than the one that yielded control will be considered by the thread scheduler.

Thread.yield():线程自愿让出cpu控制权

A thread implicitly yields the processor when it goes to sleep or otherwise blocks. The Thread.yield() method allows a thread to specify other times that are convenient for it to pause to allow other threads access to the processor. If you have a thread that frequently blocks on its own, there is no need to make Thread.yield() calls. But, if you have a thread that is performing a long non-blocking calculation, an occasional call to Thread.yield() can help split up the processor resources among the other threads. Be careful not to overuse Thread.yield() as some system overhead is incurred to perform a context switch between threads. As a rough guideline, try to avoid calling Thread.yield() more than five times per second.

当线程阻塞时(四种原因),线程隐式自行yield。如果线程本身经常阻塞,就没有必要显式调用yield,如果线程执行一个长时间不阻塞的大运算,调用一下能够给其他进程平分一下处理器资源。注意:不要频繁调用,因为yield时系统做上下文切换,很是耗费系统资源和时间,避免疫秒内调用五次以上的yield。

实例:PriorityYield.java

/*

* Created on 2005-7-8

*

* Java Thread Programming - Paul Hyde

* Copyright ? 1999 Sams Publishing

* Jonathan Q. Bo 学习笔记

*

*/

package org.tju.msnrl.jonathan.thread.chapter1;

/**

* @author Jonathan Q. Bo from TJU MSNRL

*

* Email:jonathan.q.bo@gmail.com

* Blog:blog.csdn.net/jonathan_q_bo

* blog.yesky.net/jonathanundersun

*

* Enjoy Life with Sun!

*

*/

public class PriorityYield {

private volatile int counter;

private Thread innerThread;

private volatile boolean stopRequest;

private boolean yield;

public PriorityYield(String name,int priority,boolean yield){

this.yield = yield;

this.counter = 0;

this.stopRequest = false;

Runnable r = new Runnable(){

public void run(){

try{

runwork();

}catch(Exception e){

System.out.println(e.getMessage());

}

}

};

innerThread = new Thread(r,name);

innerThread.setPriority(priority);

}

/** 线程主体 */

public void runwork(){

Thread.yield();

while(!this.stopRequest){

if(this.yield){

Thread.yield();

}

counter++;

double x = 0;

for(int i = 0; i < 1000; i++)//让线程处于活动状态,而不是sleep

x = Math.PI*i/Math.E;

}

}

/** 开始线程 */

public void startThread(){

this.innerThread.start();

}

/** 结束线程 */

public void stopThread(){

this.stopRequest = true;

}

public int getCounter(){

return this.counter;

}

/** 返回线程优先级和线程名 */

public String getPriorityandName(){

return "Thread:" + innerThread.getName() + "/Priority:" + innerThread.getPriority();

}

public static void runMain(boolean yield){

/*定义三个线程*/

PriorityYield[] pys = new PriorityYield[3];

pys[0] = new PriorityYield("PY0",3,yield);

pys[1] = new PriorityYield("PY1",6,yield);

pys[2] = new PriorityYield("PY2",6,yield);

try{

Thread.sleep(1000);

}catch(InterruptedException e){}

/*启动三线程*/

for(int i = 0 ; i < pys.length; i++){

pys[i].startThread();

}

long startTime = System.currentTimeMillis();

/*让线程运行一段时间*/

try{

Thread.sleep(10000);

}catch(InterruptedException e){}

/*停止线程运行*/

for(int i = 0; i < pys.length; i++){

pys[i].stopThread();

}

long stopTime = System.currentTimeMillis();

/*等线程完全停止运行*/

try{

Thread.sleep(1000);

}catch(InterruptedException e){}

/*获得三线程总计数*/

int totalCounter = 0;

for(int i = 0; i < pys.length; i++){

totalCounter += pys[i].getCounter();

}

/*输出统计结果*/

System.out.println("totalcount=" + totalCounter + " counter/ms=" + totalCounter/(stopTime - startTime));

for(int i = 0; i < pys.length; i++){

System.out.println(pys[i].getPriorityandName() + ", count=" + pys[i].counter + " ," + pys[i].counter*100/totalCounter + "%");

}

}

public static void main(String[] args) {

Runnable r =new Runnable(){

public void run(){

System.out.println("run without yield");

runMain(false);//不使用yield

System.out.println();

System.out.println("run with yield");

runMain(true);//使用yield

}

};

Thread t = new Thread(r,"PriorityYield");

t.setPriority(Thread.MAX_PRIORITY - 1);

t.start();

}

}

输出结果:

run without yield

totalcount=454665 counter/ms=45

Thread:PY0/Priority:3, count=0 ,0%

Thread:PY1/Priority:6, count=235049 ,51%

Thread:PY2/Priority:6, count=219616 ,48%

run with yield

totalcount=401611 counter/ms=40

Thread:PY0/Priority:3, count=0 ,0%

Thread:PY1/Priority:6, count=200805 ,49%

Thread:PY2/Priority:6, count=200806 ,50%

通过调用yield的对比实验很明显看出

1、 优先级高的获得更多的处理器周期

2、 同一优先级的线程又相同的运行机会

3、 调用yield不会增加性能,而是降低了cpu总周期

Also note that without yielding, the count/ms was about 76 (line 3), and when yielding was done, it was cut down to about 25 (line 10). This shows that the yielding caused a lot of context switches that brought with them some significant overhead. In this example, the excessive yielding wasted processor resources.

频繁的yield浪费处理器资源

When assigning priorities to the threads in your application, use the higher priorities only for threads that block frequently (sleeping, waiting, I/O). CPU-intensive calculations should be done with a medium- to low-priority thread to ensure that the processor is not hogged. Avoid setting a priority to Thread.MAX_PRIORITY unless the thread spends nearly all of its time blocked or is very short-lived.

给经常阻塞的线程高的优先级,给密集运算的线程中低优先级保证处理器不会被独占,避免设置优先级为Thread.MAX_PRIORITY,除非线程的生命周期特别短或者整个生命周期中基本都处于阻塞状态

Thread scheduling varies from VM to VM and from operating system to operating system. Because of these differences, prioritization should only be used to try to improve responsiveness and efficiency, and should not be relied upon for program correctness.

不同的虚拟机不同的操作系统有不同的线程调用机制,由于这些不同,线程优先级只是用来提高响应和效率的一种手段,不能作为程序正确性的依赖。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有