线程的优先级

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

线程优先级的特性

  • 线程A启动线程B,线程A和B具有相同的优先级。
  • CPU尽量将执行的资源让给优先级高的线程用,但是不一定优先级较大的线程先执行完。
  • 即使线程设有优先级,并不能保证执行先后,线程运行具有随机性。
/**
 * @description: 线程的优先级
 * @author: Cyril
 * @create: 2019/12/01
 */
public class ThreadPriority {

    static class ThreadPriorityDemo1 extends Thread {
        @Override
        public void run() {
            super.run();
            //线程的优先级
            System.out.println("ThreadPriorityDemo1线程的优先级" + this.getPriority());
        }
    }

    static class ThreadPriorityDemo2 extends Thread {
        @Override
        public void run() {
            super.run();
            System.out.println("ThreadPriorityDemo2的线程优先级" + this.getPriority());
        }
    }

    public static void main(String[] args) {
        ThreadPriorityDemo1 threadPriorityDemo1 = new ThreadPriorityDemo1();
        threadPriorityDemo1.start();
        Thread.currentThread().setPriority(10);
        //当前线程优先级设置位10,threadPriorityDemo2的线程优先级也会编程10
        ThreadPriorityDemo2 threadPriorityDemo2 = new ThreadPriorityDemo2();
        threadPriorityDemo2.start();
    }


}
/**
 * @description: 线程优先级执行的效率,线程优先级高的线程不一定先执行完
 * @author: Cyril
 * @create: 2019/12/01
 */
public class ThreadPriorityEfficiency {

    static class ThreadPriorityEfficiency1 extends Thread {
        @Override
        public void run() {
            long start = System.currentTimeMillis();
            System.out.println("------1------ thread 1 start running");
            long count = 0;
            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < 50000; j++) {
                    Random random = new Random();
                    random.nextInt();
                    count = count + i;
                }
            }
            long end = System.currentTimeMillis();
            System.out.println("------1------ thread 1 use time = " + (end - start));
        }
    }

    static class ThreadPriorityEfficiency2 extends Thread {
        @Override
        public void run() {
            long start = System.currentTimeMillis();
            System.out.println("------2------ thread 2 start running");
            long count = 0;
            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < 50000; j++) {
                    Random random = new Random();
                    random.nextInt();
                    count = count + i;
                }
            }
            long end = System.currentTimeMillis();
            System.out.println("------2------ thread 2 use time = " + (end - start));
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            ThreadPriorityEfficiency1 threadPriorityEfficiency1 = new ThreadPriorityEfficiency1();
            threadPriorityEfficiency1.setPriority(1);
            ThreadPriorityEfficiency2 threadPriorityEfficiency2 = new ThreadPriorityEfficiency2();
            threadPriorityEfficiency2.setPriority(10);
            //线程优先级分别设置位1、10,线程threadPriorityEfficiency2执行时间也会高于threadPriorityEfficiency1的执行时间
            threadPriorityEfficiency1.start();
            threadPriorityEfficiency2.start();
        }
    }
}

守护线程

Java中的线程分为2种:用户线程和守护线程。
用户线程:执行用户级的任务。
  • Java虚拟机在"用户线程"都结束后会退出。
守护线程:后台线程,一般用于执行后台任务。
  • 守护线程是指在程序运行的时候在后台提供一种通用服务的线程。
  • 守护线程并不属于程序中不可或缺的部分。如垃圾回收线程。
  • 当所有的用户线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。
怎么设置线程为守护线程。
  • 守护线程并非只有虚拟机内部特有的。
  • Thread.setDaemon()方法可以设置守护线程。
  • 如果想设置线程有守护线程,必须在线程运行前设置,
    否则会抛IllegalThreadStateException异常。
  • 守护线程创建的子线程也是守护线程。

如何判断一个线程是守护线程?

isDaemon()方法来区分:如果返回false,则说明该线程是“用户线程”;否则就是“守护线程”
/**
 * @description:
 * @author: Cyril
 * @create: 2019/12/01
 */
public class DaemonThreadDemo {

    public static void main(String[] args) {
        Thread t1 = new CommonThread();
        Thread t2 = new Thread(new MyDaemon());
        // 抛异常 :IllegalThreadStateException
//        t2.start();
        //设置为守护线程
        t2.setDaemon(true);
        // 正确做法:线程运行前设置守护线程
        t2.start();
        t1.start();
    }


    /**
     * 普通用户线程
     */
    static class CommonThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println("用户线程第" + i + "次执行!");
                try {
                    Thread.sleep(10);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 守护线程
     */
    static class MyDaemon implements Runnable {
        @Override
        public void run() {
            for (long i = 0; i < 9999999; i++) {
                System.out.println("守护线程第" + i + "次执行!");
                try {
                    Thread.sleep(10);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}