首页 > 技术文章 > 多线程:(优先级、守护线程)

zhai1997 2020-05-28 10:45 原文

1、线程的优先级

(1)概念

提供一个线程调度器来监控程序中启动后,进入就绪状态的所有线程,线程调度器按照优先级决定应调动哪一个线程来执行,线程的优先级用数字表示,范围是1~10

(2)程序

public class PriorityTest implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"----"+Thread.currentThread().getPriority());
    }

    public static void main(String[] args) {
        PriorityTest priorityTest=new PriorityTest();
        System.out.println(Thread.currentThread().getName()+"----"+Thread.currentThread().getPriority());
        Thread thread1=new Thread(priorityTest);
        Thread thread2=new Thread(priorityTest);
        Thread thread3=new Thread(priorityTest);
        Thread thread4=new Thread(priorityTest);
        
        thread1.start();//5

        thread2.setPriority(1);//1
        thread2.start();

        thread3.setPriority(4);//4
        thread3.start();

        thread4.setPriority(Thread.MAX_PRIORITY);//10
        thread4.start();
    }
}

测试:

main----5
Thread-3----10
Thread-0----5
Thread-2----4
Thread-1----1

线程的默认优先级为5,优先级低只是意味着获得调度的概率低,并不一定是高优先级的先被调度

 

2、守护线程

线程分为守护线程和用户线程,虚拟机必须确保用户线程执行完毕,不用等待守护线程(垃圾回收)执行完毕

(1)定义用户线程:

public class You implements Runnable{
    @Override
    public void run() {
        for (int i=0;i<36500;i++){
            System.out.println("happy every day");
        }
        System.out.println("goodbye world!");
    }
}

(2)定义守护线程:

public class God implements Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("上帝保佑着你");
        }
    }
}

(3)测试:

public class GodAndYouTest {
    public static void main(String[] args) {
        God god=new God();
        You you=new You();

        Thread thread=new Thread(god);
        thread.setDaemon(true);//默认是false,表示是用户线程,正常的线程都是用户线程
        thread.start();

        new Thread(you).start();//用户线程启动
    }
}

将God线程设置为守护线程后后启动,就是将setDaemon设置为false,任何线程都可以设置为守护线程和用户线程,通过方法 Thread.setDaemon(boolon);true 则把该线程设置为守护线程,反之则为用户线程。Thread.setDaemon()必须在 Thread.start()之前调用,否则运行时会抛出异常。

goodbye world!
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
上帝保佑着你
Process finished with exit code 0

守护线程设置的是死循环,但是该线程并没有一直循环下去,而是在用户线程停止之后,守护线程也就停止了

(4)用户线程与守护线程的区别

  唯一的区别是判断虚拟机(JVM)何时离开,守护线程是为其他线程提供服务,如果全部的用户线程已经撤离,守护线程就没有可服务的线程了,JVM 撤离。也可以理解为守护线程是 JVM 自动创建的线程(但不一定),用户线程是程序创建的线程;比如 JVM 的垃圾回收线程是一个守护线程,当所有线程已经撤离,不再产生垃圾,守护线程自然就没事可干了,当垃圾回收线程是 Java 虚拟机上仅剩的线程时,Java 虚拟机会自动离开。

 

推荐阅读