003-三、网络编程之线程优先级和守护详解
一、线程优先级
线程可以划分优先级,优先级分为1-10的10个等级,数字越大优先级越高,优先级较高的线程得到CPU
资源较多,也就是CPU
优先执行优先级较高的线程对象中的任务(其实并不是这样)。但是线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。
二、优先级具有继承性
线程是有继承关系的,比如当A线程中启动B线程,那么B和A的优先级将是一样的。
/**
* 线程优先级
*/
public class TheadTest4 {
public static void main(String[] args) {
Thread thread = new Thread(new A());
thread.start();
}
}
class A implements Runnable {
@Override
public void run() {
System.out.println("A的优先级为:" + Thread.currentThread().getPriority());
Thread thread = new Thread(new B());
thread.start();
}
}
class B implements Runnable {
@Override
public void run() {
System.out.println("B的优先级为:" + Thread.currentThread().getPriority());
}
}
三、setPriority设置优先级
更改线程的优先级。当使用了setPriority
设置了优先级,但是线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。
/**
* 线程优先级
*/
public class TheadTest4 {
public static void main(String[] args) {
Thread thread1 = new Thread(new A());
Thread thread2 = new Thread(new B());
//将优先级设置到最低
thread1.setPriority(10);
//将优先级设置到最高
thread2.setPriority(1);
//线程启动
thread1.start();
thread2.start();
}
}
class A implements Runnable {
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
System.out.println("A的优先级为:" + Thread.currentThread().getPriority());
}
}
}
class B implements Runnable {
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
System.out.println("B的优先级为:" + Thread.currentThread().getPriority());
}
}
}
//结果执行了好几次才出现的结果:
A的优先级为:10
B的优先级为:1
A的优先级为:10
B的优先级为:1
A的优先级为:10
B的优先级为:1
A的优先级为:10
A的优先级为:10
A的优先级为:10
A的优先级为:10
A的优先级为:10
A的优先级为:10
B的优先级为:1
A的优先级为:10
B的优先级为:1
B的优先级为:1
B的优先级为:1
B的优先级为:1
B的优先级为:1
B的优先级为:1
这就表示优先级低的线程不是非得优先级高的线程执行完毕之后才执行的,这也可以说明线程就是随机性的!
四、守护线程
守护线程是一种特殊的线程,它属于是一种陪伴线程。简单点说 java
中有两种线程:用户线程和守护线程。可以通过isDaemon()
方法来区别它们:如果返回false
,则说明该线程是“用户线程”;否则就是“守护线程”。
用户线程一般用于执行用户级任务,而守护线程也就是“后台线程”,一般用来执行后台任务。
需要注意的是:Java
虚拟机在“用户线程”都结束后会退出,所以守护线程也会随之结束。注意:主线程main是用户线程。
做一个小例子吧!!!
ublic class TheadTest4 {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new A());
//设置名称为A
thread1.setName("A...");
//设置为守护线程
thread1.setDaemon(true);
thread1.start();
Thread thread2 = new Thread(new A());
//设置名称为B
thread2.setName("B...");
thread2.start();
Thread.sleep(3000);
//直接中断非守护线程
thread2.interrupt();
Thread.sleep(10000);
System.out.println("程序结束!!!");
}
}
class A implements Runnable {
private int i;
@Override
public void run() {
try {
while (true) {
i++;
System.out.println("线程名称:"+Thread.currentThread().getName()+",i=" + i + ",是否为守护线程:" + Thread.currentThread().isDaemon());
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("线程名称:"+Thread.currentThread().getName()+"中断线程了");
}
}
}
//结果:
线程名称:A...,i=1,是否为守护线程:true
线程名称:B...,i=1,是否为守护线程:false
线程名称:A...,i=2,是否为守护线程:true
线程名称:B...,i=2,是否为守护线程:false
线程名称:B...,i=3,是否为守护线程:false
线程名称:A...,i=3,是否为守护线程:true
线程名称:B...中断线程了
线程名称:A...,i=4,是否为守护线程:true
线程名称:A...,i=5,是否为守护线程:true
线程名称:A...,i=6,是否为守护线程:true
线程名称:A...,i=7,是否为守护线程:true
线程名称:A...,i=8,是否为守护线程:true
线程名称:A...,i=9,是否为守护线程:true
线程名称:A...,i=10,是否为守护线程:true
线程名称:A...,i=11,是否为守护线程:true
线程名称:A...,i=12,是否为守护线程:true
线程名称:A...,i=13,是否为守护线程:true
程序结束!!!
从上面的代码可以看出来,B是用户线程当它中断了之后守护线程还没有结束,是因为主线程(用户线程)还没有结束,所以说明是所有的用户线程结束之后守护线程才会结束。
五、习题
从以上的例子大家应该还不知道守护线程到底有什么用处!!!所以现在为大家布置一个真实场景的习题。
需求:创建一个用户线程是向一个目录里面存储文件,再启动一个守护线程定时删除这个目录里面创建时间五秒前或者1分钟前创建的文件。
写完了如果写得有什么问题,希望读者能够给小编留言,也可以点击[此处扫下面二维码关注微信公众号](https://www.ycbbs.vip/?p=28 "此处扫下面二维码关注微信公众号")
看完两件小事
如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:
- 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
- 关注公众号 「方志朋」,公众号后台回复「666」 免费领取我精心整理的进阶资源教程
本文著作权归作者所有,如若转载,请注明出处
转载请注明:文章转载自「 Java极客技术学习 」https://www.javajike.com