java的线程优先级和守护线程

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就会终止运行:
(01) 调用了exit()方法,并且exit()有权限被正常执行。
(02) 所有的“非守护线程”都死了(即JVM中仅仅只有“守护线程”)。

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

 

2. 线程优先级的示例

我们先看看优先级的示例 

 1 class MyThread extends Thread{  
 2     public MyThread(String name) {
 3         super(name);
 4     }
 5 
 6     public void run(){
 7         for (int i=0; i<5; i++) {
 8             System.out.println(Thread.currentThread().getName()
 9                     +"("+Thread.currentThread().getPriority()+ ")"
10                     +", loop "+i);
11         }
12     } 
13 }; 
14 
15 public class Demo {  
16     public static void main(String[] args) {  
17 
18         System.out.println(Thread.currentThread().getName()
19                 +"("+Thread.currentThread().getPriority()+ ")");
20 
21         Thread t1=new MyThread("t1");    // 新建t1
22         Thread t2=new MyThread("t2");    // 新建t2
23         t1.setPriority(1);                // 设置t1的优先级为1
24         t2.setPriority(10);                // 设置t2的优先级为10
25         t1.start();                        // 启动t1
26         t2.start();                        // 启动t2
27     }  
28 }

 

运行结果

 

main(5)
t2(10), loop 0
t2(10), loop 1
t2(10), loop 2
t2(10), loop 3
t2(10), loop 4
t1(1), loop 0
t1(1), loop 1
t1(1), loop 2
t1(1), loop 3
t1(1), loop 4

 

结果说明
(01) 主线程main的优先级是5。
(02) t1的优先级被设为1,而t2的优先级被设为10。cpu在执行t1和t2的时候,根据时间片轮循调度,所以能够并发执行。

 

3. 守护线程的示例

下面是守护线程的示例。

 

 

 

 

package com.thread.model.threads;


/**
 * Hello world!
 *
 */
public class ThreadClass 
{
    public static void main( String[] args )
    {
        Thread thread = new Thread(new Runnable() {

            public void run() {
                while(true) {
                    try {
                        System.out.println("守护线程心跳一次");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        
        });
        
    thread.setDaemon(true);//将该线程设置为守护线程
        
    thread.start();
        
    try {
        Thread.sleep(10000);
        Thread currentthread = Thread.currentThread();
        System.out.println("主线程"+currentthread.getName()+"退出!");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
 }

}

得出的结果是:

发现主线程一旦退出,守护线程也就不再运行,直接退出了。

 

那如果主线程启动了两个线程,一个是守护线程,一个是用户线程,主线程退出,守护线程会不会退出呢?我们来测试一下

package com.thread.model.threads;


/**
 * Hello world!
 *
 */
public class ThreadClass 
{
    public static void main( String[] args )
    {
        Thread thread1 = new Thread(new Runnable() {

            public void run() {
                while(true) {
                    try {
                        Thread currentthread1 = Thread.currentThread();
                        System.out.println("守护线程"+currentthread1.getName()+"心跳一次");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                 }
            }
        
        });
        
    thread1.setDaemon(true);//将该线程设置为守护线程
       
    thread1.start();
        
    Thread thread2 = new Thread(new Runnable() {


    public void run() {
        while(true) {
            try {
                Thread currentthread2 = Thread.currentThread();
                System.out.println("用户线程"+currentthread2.getName()+"心跳一次");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
        
    });
        
    thread2.start();
        
    try {
        Thread.sleep(10000);
        Thread currentthread = Thread.currentThread();
        System.out.println("主线程"+currentthread.getName()+"退出!");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    }
}

主线程退出后,守护线程依然在运行!

总结:

1.用户线程和守护线程的区别
用户线程和守护线程都是线程,区别是Java虚拟机在所有用户线程dead后,程序就会结束。而不管是否还有守护线程还在运行,若守护线程还在运行,则会马上结束。很好理解,守护线程是用来辅助用户线程的,如公司的保安和员工,各司其职,当员工都离开后,保安自然下班了。

2.用户线程和守护线程的适用场景
由两者的区别及dead时间点可知,守护线程不适合用于输入输出或计算等操作,因为用户线程执行完毕,程序就dead了,适用于辅助用户线程的场景,如JVM的垃圾回收,内存管理都是守护线程,还有就是在做数据库应用的时候,使用的数据库连接池,连接池本身也包含着很多后台线程,监听连接个数、超时时间、状态等。

3.创建守护线程
调用线程对象的方法setDaemon(true),设置线程为守护线程。
1)thread.setDaemon(true)必须在thread.start()之前设置。
2)在Daemon线程中产生的新线程也是Daemon的。
3)不是所有的应用都可以分配给Daemon线程来进行服务,比如读写操作或者计算逻辑。因为Daemon Thread还没来得及进行操作,虚拟机可能已经退出了。

4.Java守护线程和Linux守护进程
两者不是一个概念。Linux守护进程是后台服务进程,没有控制台。
在Windows中,你可以运行javaw来达到释放控制台的目的,在Unix下你加&在命令的最后就行了。所以守护进程并非一定需要的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值