• 【Java并发】聊聊如何优雅的暂停一个线程以及LockSupport


    在面试中并发编程会经常问到一个问题,那就是如何优雅的暂停一个线程。比如T1线程暂停正在执行的T2线程。

    中断

    java中提供了stop方法,但是已经被废弃了,原因是这种会直接暂停一个线程,强制执行。但是java采用另一种方式也就是中断,
    具体就是其他线程或者本线程调用interrupt(),会将线程的中断标识设置为true。然后线程不断检查这个状态,如果如何就直接退出。
    而检查的方式就是通过调用isInterrupted()方法。
    在这里插入图片描述

    public class DemoInterrupt implements Runnable {
    
        @Override
        public void run() {
            System.out.println("线程开始执行");
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("线程被中断,退出");
                break;
            }
            System.out.println("程序退出");
        }
    
    
        public static void main(String[] args) throws InterruptedException {
            DemoInterrupt demoInterrupt = new DemoInterrupt();
            Thread thread = new Thread(demoInterrupt);
            thread.start();
    
            Thread.sleep(1000);
            System.out.println("线程中断");
            thread.interrupt();
            System.out.println("执行完毕");
    
    
            Thread.sleep(1000);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    从执行结果来看,其实interrupt();只是将中断标记设置为true,需要等线程执行完毕,才会停止。
    在这里插入图片描述

    java.lang.InterruptedException: sleep interrupted
    	at java.lang.Thread.sleep(Native Method)
    	at com.jia.interrupt.DemoInterrupt.run(DemoInterrupt.java:17)
    	at java.lang.Thread.run(Thread.java:748)
    
    • 1
    • 2
    • 3
    • 4
    try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                e.printStackTrace();
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    在这里插入图片描述
    上述的方式其实就是两阶段终止模式,也就是先发送终止指令,然后在执行响应终止指令。
    在这里插入图片描述

    LockSupport

    我们知道LockSupport的park和unpark 是用来阻塞线程和解除线程阻塞。那么其实syn中的wait和notify,以及condition的await和singal其实也可以实现线程等待。为什么需要Locksupport,主要是因为syn和lock的阻塞的是整个代码块,而lockSupport阻塞的只是当前的线程,阻塞的粒度更小。
    在这里插入图片描述

    public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"线程执行");
                LockSupport.park();
                System.out.println(Thread.currentThread().getName()+"线程完毕");
            });
            thread.start();
    
            Thread.sleep(1000);
            LockSupport.unpark(thread);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    public static void park() {
            UNSAFE.park(false, 0L);
        }
    
    public static void unpark(Thread thread) {
            if (thread != null)
                UNSAFE.unpark(thread);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    小结

    本篇文章主要介绍了如何优雅暂停一个线程,以及使用lockSupport进行阻塞和唤醒一个线程。

  • 相关阅读:
    ForkJoinPool的使用及基本原理
    【Linux驱动开发】点亮一个LED的三种字符设备驱动框架
    Spring+SpringMVC+Jsp实现校园二手交易系统
    互融云供应链金融软件平台 实现多渠道数据连接整合
    web课程设计网页规划与设计——惊奇漫画网站
    算法通关村第一关——链表白银挑战笔记
    go语言实现十大排序算法
    文件上传漏洞详解
    深度解析智能运维场景下“港口行业”解决方案
    Redis常见数据类型及其常用命令详解
  • 原文地址:https://blog.csdn.net/jia970426/article/details/133197615