Java
Java多线程

Java多线程 08 - 线程的优先级

简介:Java中的线程优先级的范围是1~10,默认的优先级是5。高优先级线程会优先于低优先级线程执行。

1. 线程优先级介绍

Java中的线程优先级的范围是1~10,默认的优先级是5。高优先级线程会优先于低优先级线程执行。

Java中有两种线程:用户线程和守护线程。可以通过isDaemon()方法来区别它们:如果返回false,则说明该线程是用户线程,否则就是守护线程。用户线程一般用户执行用户级任务,而守护线程也就是后台线程,一般用来执行后台任务。需要注意的是,Java虚拟机在用户线程都结束后会后退出。

JDK中关于线程优先级和守护线程的介绍如下:

Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon. When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.
When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.

大致意思是:

每个线程都有一个优先级。高优先级线程会优先于低优先级线程执行。每个线程都可以被标记为一个守护进程或非守护进程。在一些运行的主线程中创建新的子线程时,子线程的优先级被设置为等于创建它的主线程的优先级,当且仅当创建它的主线程是守护线程时子线程才会是守护线程。

当Java虚拟机启动时,通常有一个单一的非守护线程(该线程通过是通过main()方法启动)。JVM会一直运行直到下面的任意一个条件发生,JVM就会终止运行:

  1. 调用了exit()方法,并且exit()有权限被正常执行。
  2. 所有的非守护线程都死了(即JVM中仅仅只有守护线程)。

每一个线程都被标记为守护线程或用户线程。当只有守护线程运行时,JVM会自动退出。

2. 线程优先级的示例

我们先看看优先级的示例:

  • public class PriorityTest {
  • public static void main(String[] args) {
  • // 线程1
  • Thread thread1 = new Thread(new Runnable() {
  • @Override
  • public void run() {
  • for (int i = 0; i < 5; i++) {
  • System.out.println(Thread.currentThread().getName() + "(" + Thread.currentThread().getPriority() + ")" + ", execute " + i);
  • }
  • }
  • });
  • // 线程2
  • Thread thread2 = new Thread(new Runnable() {
  • @Override
  • public void run() {
  • for (int i = 0; i < 5; i++) {
  • System.out.println(Thread.currentThread().getName() + "(" + Thread.currentThread().getPriority() + ")" + ", execute " + i);
  • }
  • }
  • });
  • // 设置两个子线程的优先级
  • thread1.setPriority(10);
  • thread2.setPriority(1);
  • // 打印主线程的相关信息
  • System.out.println(Thread.currentThread().getName() + "(" + Thread.currentThread().getPriority() + ")" + ", execute ");
  • // 启动两个子线程
  • thread1.start();
  • thread2.start();
  • }
  • }

运行结果如下:

  • main(5), execute
  • Thread-0(10), execute 0
  • Thread-0(10), execute 1
  • Thread-1(1), execute 0
  • Thread-0(10), execute 2
  • Thread-1(1), execute 1
  • Thread-0(10), execute 3
  • Thread-1(1), execute 2
  • Thread-0(10), execute 4
  • Thread-1(1), execute 3
  • Thread-1(1), execute 4

从结果中可以看出,主线程的优先级是5,两个子线程的优先级分别为10和1,将会交替执行。

3. 守护线程的示例

下面是守护线程的示例:

  • public class DaemonTest {
  • public static void main(String [] args) {
  • // 线程1
  • Thread thread1 = new Thread(new Runnable() {
  • @Override
  • public void run() {
  • for (int i = 0; i < 5; i++) {
  • System.out.println(Thread.currentThread().getName() + "(" + Thread.currentThread().isDaemon() + ")" + ", execute " + i);
  • }
  • }
  • });
  • // 线程2
  • Thread thread2 = new Thread(new Runnable() {
  • @Override
  • public void run() {
  • for (int i = 0; i < 1000; i++) {
  • System.out.println(Thread.currentThread().getName() + "(" + Thread.currentThread().isDaemon() + ")" + ", execute " + i);
  • }
  • }
  • });
  • // 设置thread2为守护线程
  • thread2.setDaemon(true);
  • // 启动两个子线程
  • thread1.start();
  • thread2.start();
  • }
  • }

运行结果如下:

  • Thread-0(false), execute 0
  • Thread-0(false), execute 1
  • Thread-1(true), execute 0
  • Thread-0(false), execute 2
  • Thread-0(false), execute 3
  • Thread-0(false), execute 4
  • Thread-1(true), execute 1
  • Thread-1(true), execute 2
  • Thread-1(true), execute 3
  • Thread-1(true), execute 4
  • Thread-1(true), execute 5
  • Thread-1(true), execute 6
  • Thread-1(true), execute 7
  • Thread-1(true), execute 8

从运行结果可以得知,虽然Thread-1为守护线程,但当Thread-0和主线程执行结束后,Thread-1线程也停止执行了。