线程的优先级
在操作系统中,线程可以划分优先级,优先级高的线程得到CPU执行权的机会多,也就是说优先级高的线程可能会先执行。
setPriority()方法可以设置线程的优先级,一般线程的优先级数值是1~10,如果超过这个范围会抛出异常IllegalArguementException。
1.10.1 线程优先级的继承性
什么是优先级的继承性?就是说如果优先级为5的线程A启动了线程B,那么这时候线程B的优先级也就是5,比如我们将主线程设置的优先级设置为1,那么主线程启动了A线程,这时A线程的优先级也应该是1。
public class MyThread1 extends Thread {
@Override
public void run() {
System.out.println("MyThread1 run priority = " + this.getPriority());
MyThread2 thread2 = new MyThread2();
thread2.start();
}
}
public class MyThread2 extends Thread {
@Override
public void run() {
System.out.println("Mythread2 run priority = " + this.getPriority());
}
}
package cn.zxyy.multiThread.Thread.priority;
/*
* 线程的优先级具有继承性,默认值是5
* 然后如果是A线程启动了B线程,那么B线程的优先级会与A线程一样
* */
public class Run {
public static void main(String[] args) {
//这里main线程的值是5
System.out.println("main thread begin priority = " + Thread.currentThread().getPriority());
//先注释这一行 Thread.currentThread().setPriority(6);
//运行结果是5,main线程的优先级没有改变,它启动了thread1线程,所以根据继承性,thread1的优先级也是5
System.out.println("main thread end priority = " +Thread.currentThread().getPriority());
MyThread1 thread1 = new MyThread1();
//然后thread1启动了thread2 ,所以thread2的优先级也是5
thread1.start();
}
}
从上面的运行结果可以看到,如果不设置优先级,默认的数值是5,由于主线程启动了myThread1线程,这是myThread1的优先级就是5,因为myThread1启动了myThread2,所以myThread2的优先级也是5。
然后再取消注释,主线程优先级默认为5,我们将其设置为6,后面myThread1和myThread2的优先级都变成了6,这就是线程优先级的继承性。
1.10.2 优先级具有规则性
优先级具有规则性:就是优先级高的线程一般都是先执行完。
package cn.zxyy.multiThread.Thread.priorityRule;
import java.util.Random;
public class MyThread1 extends Thread {
@Override
public void run() {
long beginTime = System.currentTimeMillis();
long addResult = 0L;
for (int j = 0; j < 10; j++) {
for (int i = 0; i < 50000; i++) {
Random random = new Random();
random.nextInt();
addResult = addResult + i;
}
}
long endTime = System.currentTimeMillis();
System.out.println(" ###### thread1 use time = " + (endTime - beginTime));
}
}
package cn.zxyy.multiThread.Thread.priorityRule;
import java.util.Random;
public class MyThread2 extends Thread {
@Override
public void run() {
long beginTime = System.currentTimeMillis();
long addResult = 0L;
for (int j = 0; j < 10; j++) {
for (int i = 0; i < 50000; i++) {
Random random = new Random();
random.nextInt();
addResult = addResult + i;
}
}
long endTime = System.currentTimeMillis();
System.out.println(" $$$$$$ thread2 use time = " + (endTime - beginTime));
}
}
package cn.zxyy.multiThread.Thread.priorityRule;
public class Run {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
MyThread1 myThread1 = new MyThread1();
myThread1.setPriority(1);
myThread1.start();
MyThread2 myThread2 = new MyThread2();
myThread2.setPriority(10);
myThread2.start();
}
}
}
从运行结果可以看到,第一次将thread1优先级设置为3,thread2优先级设置为4。第二次将thread1优先级设置为1,thread2优先级设置为10。可以看到优先级高的线程一般都是先执行完。
注:值越大,优先级越高,10是最高的优先级,1是最低的优先级。
1.10.3 优先级具有随机性
上面我们说到了优先级的规则性:优先级高的线程一般都是先执行完。之所以不能说成优先级高的线程一定先执行完,是因为优先级也具有随机性,不是每次都是优先级高的线程先执行完。
1.10.4 看谁运行得快
一般情况下优先级高的线程运行时间快。
package cn.zxyy.multiThread.Thread.countPriority;
public class MyThread1 extends Thread {
private long count = 0 ;
public long getCount() {
return count;
}
@Override
public void run() {
while(true){
count++;
}
}
}
package cn.zxyy.multiThread.Thread.countPriority;
public class MyThread2 extends Thread {
private long count = 0 ;
public long getCount() {
return count;
}
@Override
public void run() {
while(true){
count++;
}
}
}
package cn.zxyy.multiThread.Thread.countPriority;
public class Run {
public static void main(String[] args) {
try{
MyThread1 a = new MyThread1();
a.setPriority(2);
a.start();
MyThread2 b = new MyThread2();
b.setPriority(8);
b.start();
Thread.sleep(20000);
a.stop();
b.stop();
System.out.println("a = " + a.getCount());
System.out.println("b = " + b.getCount());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
1.11 守护线程
Java中有两种线程,一种是用户线程,另外一种就是守护线程(Daemon);
守护线程就是一种特殊的线程,顾名思义守护,陪伴某些线程。
当非守护线程结束了,那么守护线程也就自动销毁了。最典型的守护线程就是垃圾回收线程,当进程中没有非守护线程了,那么垃圾回收线程也就自动销毁了。
当有多个非守护线程的时候,只要有其中一个非守护线程没有结束,那么守护线程就还要存在,但是当所有非守护线程都执行完毕,这时候守护线程也就可以一起结束工作了。
package cn.zxyy.multiThread.Thread.daemonThread;
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();
}
}
}
package cn.zxyy.multiThread.Thread.daemonThread;
public class Run {
public static void main(String[] args) {
try{
MyThread myThread = new MyThread();
myThread.setDaemon(true);
myThread.start();
Thread.sleep(5000);
System.out.println("我离开myThread对象也不再打印了,也就是停止了");
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
总结:
1.线程的优先级具有继承性:线程被哪个线程启动,就继承哪个线程的优先级。
2.线程的优先级具有规则性:一般情况下,优先级高的线程会先执行完。
3.线程的优先级具有随机性:并不是每次都是优先级高的线程先执行完。
4.一般情况下,优先级高的线程执行的速度会比较快。
5.守护线程一定是等到所有的非守护线程全部执行完毕,才会自动销毁,垃圾回收线程就是一个守护线程。