美文网首页
Java线程简介

Java线程简介

作者: Lebens | 来源:发表于2018-05-08 10:49 被阅读0次

    主要是介绍一些线程相关的知识点,包括线程的生命周期,守护线程等,为后续的博客做一些铺垫。

    什么是线程

    关于什么是线程,网上一大堆的介绍:

    相对于进程,线程是操作系统(OS)调度的最小执行单元

    线程的特点,根据线程的官方介绍可以看出:

    1. java应用可以同时执行多个线程
    2. 每个线程都有优先级,优先级高的线程优先于低优先级的线程执行
    3. 线程在创建时可以设置为守护线程
    4. 虚拟机启动时会有一个非守护线程的,也就是main方法所在的线程
    5. 当一个应用程序所有的非守护线程死亡时,jvm退出,同时所有守护线程被销毁
    6. 线程的创建有2种方式:继承Thread类并覆写run方法;在构造时传入一个Runnable实现类参数
    7. 每个线程都有一个名字用于标识线程

    几个点需要说一下:

    1. 当设置一个线程为守护线程时,只能在调用Start()方法前设置,否则抛出异常
    2. 线程优先级分为1-10,默认为5
    3. 死亡的线程无法再次被运行

    线程的生命周期

    线程的生命周期分为新建状态就绪状态运行状态阻塞状态死亡状态 5种状态,这5种状态的转换如下图所示:

    线程生命周期图.jpeg
    1. 调用new关键字,新建一个Thread实例对象有,实例对象就处于新建状态。
    2. 当Thread实例对象调用start()后,进入就绪状态可以被cpu调度执行。
    3. 就绪状态的Thread实例对象,在获取到cpu执行权后就可以运行。同时由于cpu的切换或者调用了线程的yield方法,会导致运行状态的Thread回到就绪状态。
    4. 当运行状态的线程遇到如下几种情况时将进入阻塞状态
      • wait()
      • sleep()
      • join()
      • 等待同步锁
      • 阻塞式I/O调用
    5. 阻塞状态的线程恢复进入就绪状态,当然在阻塞时线程被中断,那么线程进入死亡状态。
    6. 运行状态的线程正常运行完毕或者中断异常都将进入死亡状态。

    守护线程

    相对于正常线程,也就是所谓的用户线程来说,守护线程主要是用于为用户线程提供便利,这也是守护这个词的含义,最典型的就是java系统的GC线程。

    当所有用户线程退出时,守护线程就没有服务对象也没有存在的意义,所以随着jvm的退出,所有的守护线程都会被销毁,这也就是java文档的说明。

    关于守护线程有如下几个注意点:

    1. 设置守护线程必须在线程start()之前
    2. 守护线程里执行的代码存在不完整执行的风险,所以涉及到数据计算保存的,需要有明确结果的操作不宜放在这里执行
    3. 在守护线程下新建的线程也为守护线程

    关于第一点限制也很好理解,当你把启动的用户线程设置为守护线程时,可能刚好把唯一的用户线程消灭了,然后jvm退出了,导致了第二点的问题。

    举个例子验证一下上面说的,所有用户线程退出后jvm退出导致守护线程销毁的说法:

    public class ThreadTest {
    
        public static void main(String[] args) {
    
            try {
                Thread thread = new Thread() {
                    @Override
                    public void run() {
                        try {
                            int i = 0;
                            while (true) {
                                System.out.println(i++);
                                Thread.sleep(200);
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                thread.setDaemon(true);
                thread.start();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    打印结果如下:

    0
    1
    2
    3
    4
    
    Process finished with exit code 0
    

    结果也很明显,每200毫秒打印一个数字,等主线程sleep结束就退出了。

    如果把thread.setDaemon(true);注释调可以看到,线程一直会打印到底。

    总结

    1. 线程有5种状态:新建状态就绪状态运行状态阻塞状态死亡状态
    2. 线程有2种创建方式
    3. 线程有优先级
    4. 线程有名字
    5. 守护线程需要在start()之前指定
    6. 守护线程代码可能执行不完整
    7. 守护线程下新建的都是守护线程

    相关文章

      网友评论

          本文标题:Java线程简介

          本文链接:https://www.haomeiwen.com/subject/kfyirftx.html