JAVA知识之多线程(二):生命周期和守护线程

1.线程常用API

  • public void start()
    开始执行一个线程,调用run()方法。注意同一个线程不可以多次调用start()方法.
  • public static Thread currentThread()
    获取当前线程对象
  • public String getName()
    获取线程名字
  • public Thread.State getState()
    获取线程状态
  • public void interrupt()
    中断线程
  • public void join() /public void join(long millis)
    等待线程结束 / 等待线程结束时间最长为millis毫秒
  • public void setDaemon(boolean on)
    将线程标记为用户线程(普通线程)或者守护线程
  • public static void sleep(long millis)
    让正在执行的线程休眠millis毫秒
  • public static void yield()
    暂停当前线程,执行其他线程

2.线程的生命周期

线程的主要状态共有六种,分别是:
1. NEW(新建状态)
2. RUNNABLE(就绪状态)
3. BLOCKED(阻塞状态)
4. WAITING(等待状态)
5. TIMED_WAITING(等待指定时间状态)
6. TERMINATED(退出状态)

我在网上看到过一个线程状态的转换图,很直观:
这里写图片描述
PS:图片出自csdn博客Allen Iverson,图片转载需要注明出处。

简单解释一下,我们使用构造方法获得线程对象的时候,线程进入新建状态,调用线程start()方法,线程进入就绪状态,系统分配资源时,进入运行状态,调用sleep()方法,线程进入等待状态,调用wait()方法,线程进入阻塞状态,当wait()时间结束或者join()线程结束,线程会回到就绪状态,当run()方法结束,线程进入死亡状态。

3.守护线程和用户线程

线程分为两种,一种是用户线程(User Thread),另一种是守护线程(Daemon Thread)。
两种线程使用方法都是差不多的,区别在于结束方式,因为守护线程是为用户线程提供服务的,所以守护线程随着用户线程的结束而结束的,当用户线程进入死亡状态,当jvm里面没有用户线程了,守护线程自动结束运行,也进入死亡状态。
关于守护线程有三个地方需要注意:
- 必须先调用setDaemon()方法吧线程设为守护线程,然后才能start()开启运行,否则会报出java.lang.IllegalThreadStateException异常,原因是不能对正在运行的线程做线程类型设置。
- 守护线程内创建的线程也是守护线程,也是随着用户线程死亡而死亡。
- 守护线程不能执行读写操作等业务代码,因为守护线程的退出不是以程序执行完毕来结束而是由jvm控制的,因此有可能完不成预期的任务。

//用户线程
class RunnableTest implements Runnable{
    public void run() {
        //输出1到3自然数,每隔1秒输出一次
        for(int i=1; i<=3; i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("用户线程正在执行,i = " + i);
        }
        System.out.println("用户线程结束");
    }
}
//守护线程
class DaemonTest implements Runnable{
    public void run() {
        //输出1到5自然数,每隔一秒输出一次
        for(int i=1; i<=5; i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("守护线程正在执行,i = " + i);

        }
        System.out.println("守护线程结束");
    }
}

public class ThreadMain {

    public static void main(String[] args) {
        Thread userThread = new Thread(new RunnableTest());
        Thread daemonThread = new Thread(new DaemonTest());

        daemonThread.setDaemon(true);//设为守护线程
        daemonThread.start();
        userThread.start();
    }

}

运行结果如下:

我们可以看到用户线程和守护线程是在同步运行的,但是用户线程的代码全部执行完毕,而守护线程的代码却提前结束了,这就是说明当用户线程执行完毕,守护线程会提前结束运行,因此不可以使用守护线程去执行读写操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值