Java 线程

  • 什么是守护线程,什么是非守护线程?
    • java有两种状态的线程
    • 守护线程与非守护线程的区别
  • 守护线程与非守护线程代码演示区别
    • 创建守护线程
    • 守护线程:主线程销毁停止,守护线程一起销毁
    • 非守护线程:如果主线程销毁,用户线程继续运行且互不影响。

      什么是守护线程,什么是非守护线程?

      Java有两种状态的线程

  1. 守护线程(例如垃圾回收线程:gc线程)
  2. 非守护线程(用户线程:用户线程即手动创建的线程)

    守护线程与非守护线程的区别

  3. 守护线程

  • 有一个特征,例如当主线程运行的时候,垃圾回收线程一起运行。
  • 当主线程销毁,会和主线程一起销毁。
  1. 非守护线程
  • 如果主线程销毁,用户线程继续运行且互不影响。

    守护线程与非守护线程代码演示区别

    创建守护线程

    1. public static void main(String[] args) throws InterruptedException {
    2. Thread t1 = new Thread(new Runnable() {
    3. public void run() {
    4. while (true) {
    5. try {
    6. Thread.sleep(1000);
    7. } catch (Exception e) {
    8. // TODO: handle exception
    9. }
    10. System.out.println("我是子线程(用户线程)");
    11. }
    12. }
    13. });
    14. // 标识当前方法为守护线程,一定要在启动线程前设置为守护线程
    15. t1.setDaemon(true);
    16. t1.start();
    17. }

    必须在t1.start()之前设置,不能把正在运行的常规线程设置为守护线程,否则报IllegalThreadStateException异常

    守护线程:主线程销毁停止,守护线程一起销毁

    1. public static void main(String[] args) {
    2. Thread t1 = new Thread(new Runnable() {
    3. public void run() {
    4. while (true) {
    5. try {
    6. Thread.sleep(1000);
    7. } catch (Exception e) {
    8. // TODO: handle exception
    9. }
    10. System.out.println("我是子线程(用户线程)");
    11. }
    12. }
    13. });
    14. // 标识当前方法为守护线程,一定要在启动线程前设置为守护线程
    15. t1.setDaemon(true);
    16. //启动线程
    17. t1.start();
    18. //相当与主线程
    19. for (int i = 0; i < 10; i++) {
    20. try {
    21. Thread.sleep(300);
    22. } catch (Exception e) {
    23. e.printStackTrace();
    24. }
    25. System.out.println("main:i:" + i);
    26. }
    27. System.out.println("主线程执行完毕...");
    28. }

    以下为运行结果:

    1. main:i:0
    2. main:i:1
    3. main:i:2
    4. 我是子线程(用户线程)
    5. main:i:3
    6. main:i:4
    7. main:i:5
    8. 我是子线程(用户线程)
    9. main:i:6
    10. main:i:7
    11. main:i:8
    12. 我是子线程(用户线程)
    13. main:i:9
    14. 主线程执行完毕...

    主线程结束之后并没有在继续运行守护线程,守护线程也跟着结束,一起销毁停止。

    非守护线程:如果主线程销毁,用户线程继续运行且互不影响。

    1. public static void main(String[] args) {
    2. Thread t1 = new Thread(new Runnable() {
    3. public void run() {
    4. while (true) {
    5. try {
    6. Thread.sleep(1000);
    7. } catch (Exception e) {
    8. // TODO: handle exception
    9. }
    10. System.out.println("我是子线程(用户线程)");
    11. }
    12. }
    13. });
    14. //启动线程
    15. t1.start();
    16. //相当与主线程
    17. for (int i = 0; i < 10; i++) {
    18. try {
    19. Thread.sleep(300);
    20. } catch (Exception e) {
    21. e.printStackTrace();
    22. }
    23. System.out.println("main:i:" + i);
    24. }
    25. System.out.println("主线程执行完毕...");
    26. }

    以下为运行结果:

    1. main:i:0
    2. main:i:1
    3. main:i:2
    4. 我是子线程(用户线程)
    5. main:i:3
    6. main:i:4
    7. main:i:5
    8. 我是子线程(用户线程)
    9. main:i:6
    10. main:i:7
    11. main:i:8
    12. 我是子线程(用户线程)
    13. main:i:9
    14. 主线程执行完毕...
    15. 我是子线程(用户线程)
    16. 我是子线程(用户线程)
    17. 我是子线程(用户线程)
    18. 我是子线程(用户线程)
    19. 我是子线程(用户线程)
    20. 我是子线程(用户线程)
    21. 。。。。。。。。。。。。。。。。。。。。。

    当主线程销毁停止,非守护线程(用户线程)并没有结束,而是一直在执行,与主线程互不影响。