简述
在操作系统中,线程是可以划分优先级的,优先级较高的线程,得到CPU优先执行的几率就较高一些。设置线程的优先级,有助于帮助线程规划期选择下一个哪一个线程优先执行,但是线程优先级高不代表一定会优先执行,这在下文会说明原因
如何设置线程优先级
设置线程优先级的方法是 setPriority,jdk中该方法的代码如下:
public final void setPriority(int newPriority) { ThreadGroup g; checkAccess(); if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup()) != null) { if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } setPriority0(priority = newPriority); } }
在java中,线程的优先级分为1~10,这10个等级,如果优先级的值小于1或大于10,则jdk就会抛出异常 throw new IllegalArgumentException()。在jdk中使用3个常量来预定义优先级的值:
/** * 线程最小优先级 */ public final static int MIN_PRIORITY = 1; /** * 线程默认优先级 */ public final static int NORM_PRIORITY = 5; /** * 线程最大优先级 */ public final static int MAX_PRIORITY = 10;
线程优先级具有3中特性,分别是:继承性、规则性、随机性,下面将一一说明:
1、继承性
在Java中,线程的优先级具有继承性,比如线程A启动线程,则线程B的优先级与线程A是一样的
public class ThreadA extends Thread { @Override public void run() { System.out.println(" ThreadA run priority=" + this.getPriority()); ThreadB thread2 = new ThreadB(); thread2.start(); }}public class ThreadB extends Thread { @Override public void run() { System.out.println(" ThreadB run priority=" + this.getPriority()); }}public class ThreadDemo { public static void main(String[] args) { Thread.currentThread().setPriority(6); System.out.println(" main thread priority=" + Thread.currentThread().getPriority()); ThreadA threadA = new ThreadA(); threadA.start(); }}
输出结果:
main thread priority=6 ThreadA run priority=6 ThreadB run priority=6
从结果可以看出,ThreadA继承了main的优先级,ThreadB继承了ThreadA的优先级
2、规则性
public class ThreadA extends Thread { @Override public void run() { long beginTime = System.currentTimeMillis(); long aCount = 0; for (int i = 0; i < 50000; i++) { Random random = new Random(); aCount += random.nextInt() + i; } long endTime = System.currentTimeMillis(); System.out.println(" ★ ★ ★ ★ ★ thread A use time=" + (endTime - beginTime)); }}public class ThreadB extends Thread { @Override public void run() { long beginTime = System.currentTimeMillis(); long bCount = 0; for (int i = 0; i < 50000; i++) { Random random=new Random(); bCount+=random.nextInt()+i; } long endTime = System.currentTimeMillis(); System.out.println(" ☆ ☆ ☆ ☆ ☆ thread B use time=" + (endTime - beginTime)); }}public static void main(String[] args) { for (int i = 0; i < 5; i++) { ThreadA threadA = new ThreadA(); threadA.setPriority(10); threadA.start(); ThreadB threadB = new ThreadB(); threadB.setPriority(6); threadB.start(); } }
输出结果:
★ ★ ★ ★ ★ thread A use time=23 ☆ ☆ ☆ ☆ ☆ thread B use time=29 ★ ★ ★ ★ ★ thread A use time=29 ☆ ☆ ☆ ☆ ☆ thread B use time=34 ★ ★ ★ ★ ★ thread A use time=34 ★ ★ ★ ★ ★ thread A use time=36 ☆ ☆ ☆ ☆ ☆ thread B use time=38 ☆ ☆ ☆ ☆ ☆ thread B use time=37 ★ ★ ★ ★ ★ thread A use time=7 ☆ ☆ ☆ ☆ ☆ thread B use time=4
运行多次之后,我们发现高优先级的线程总是大部分先执 完,但不代表高优先级的 线程全部先执行完。说明线程的优先级具有一定的规则性,也就是CPU尽量将执行资源 让给优先级比较高的线程。
3、随机性
前面的事例证明了线程的优先级较高则优先执行完 run()方法中的任务, 但这个结果不是肯定的, 因为线程的优先级还具有随机性,也就是线程优先级高的线程并不一定每次都先执行完
。将上述事例两个线程的优先级分别调整为相近的优先级,运行多次后就会发现这种随机性。什么是守护线程
在Java线程中有两种类型的线程,一种是用户线程,另一种是守护线程。
守护线程是一种特殊的线程,典型的守护线程就是垃圾回收线程,当进程中没有用户线程了,则垃圾回收线程也就没有存在的必要了,会自动销毁。
public class MyThread extends Thread { private int i = 0; @Override public void run() { try { while (true) { i++; System.out.println(" i=" + (i)); Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } }}public class ThreadDemo { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.setDaemon(true); thread.start(); Thread.sleep(5000); System.out.println("主线程执行完毕了,守护线程也要停止了"); } catch (InterruptedException e) { e.printStackTrace(); } }}
输出结果:
i=1 i=2 i=3 i=4 i=5主线程执行完毕了,守护线程也要停止了