目录:
- 1. 线程优先级
- 2. 用户线程和守护(Daemon)线程
1. 线程优先级
Java使用的线程调度方式就是抢占式调度,每个线程将由系统来分配执行时间,线程的切换不由线程本身来决定。
可以通过设置线程的优先级给操作系统一定的调度“建议”,Java一共设置了10个级别的线程优先级。通过setPriority(int newPriority)
方法设置线程优先级。
- 之所以说是“建议”,是因为最终如何调度线程还是由操作系统说了算,也有可能先运行了低优先级的线程
- 共有10个级别的优先级:1~10
Thread.MIN_PRIORITY
:优先级1,最低级别的优先级Thread.MAX_PRIORITY
:优先级10,最高级别的优先级Thread.NORM_PRIORITY
:优先级5,默认的优先级- 操作系统的优先级并不见得能与Java线程的优先级一一对应(如Windows中只有7中优先级,当然也就无法一一对应了)
线程优先级使用举例:
public class TestPriority {
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println("所执行线程的优先级为: " + Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = null;
for (int i = 1; i <= 10; i++) {
thread = new Thread(runnable, String.valueOf(i));
thread.setPriority(i);
thread.start();
}
}
}
执行结果:
可以看到,线程优先级的确只是提供了一个“建议”,最后的执行顺序并不是按照线程优先级执行的。
2. 用户线程和守护(Daemon)线程
Java中的线程可以被分为两类:
- 用户线程
我们平时实现的一般都是用户线程,可以将其当作是系统的工作线程。
- 守护(Daemon)线程
守护线程是一种特殊的线程,它是系统的守护者,在后台默默的完成一些系统性的服务,例如:
- 垃圾回收(Garbage Collection, GC)线程
- 即时编译(Just in time, JIT)线程
Java虚拟机无需等待守护线程全部结束(因为它原本就是为应用程序服务的),如果程序中的用户线程已经全部结束,就意味着这个程序实际上已经无事可做了(守护线程要守护的对象已经不在了)。 因此,当一个程序中只有守护线程时,JVM就会自然的退出。
守护线程使用举例:
可以通过Thread对象.setDaemon(true)
将线程设置为守护线程
public class TestDaemonThread {
public static void main(String[] args) throws InterruptedException {
Thread daemonThread = new Thread(() -> {
while (true) { // 让守护线程一直在运行
System.out.println(Thread.currentThread().getName() + "is alive!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "DaemonThread");
// 将线程设置为守护线程
daemonThread.setDaemon(true);
daemonThread.start();
Date nowTime = null;
for (int i = 0; i < 5; i++) {
nowTime = new Date(System.currentTimeMillis());
System.out.println(new SimpleDateFormat("HH:mm:ss").format(nowTime));
Thread.sleep(1000);
}
System.out.println("main end!");
// 当一个程序中只有守护线程时,JVM就会自然的退出。
}
}
执行结果:
参考书籍: Java高并发程序设计(第二版)