• 线程的“打断”


    【打断线程的三个方法】:

     //Thread.java  
    public void interrupt()              //t.interrupt() 打断t线程(设置t线程某给标志位f=true,并不是打断线程的运行)
    public boolean isInterrupted()       //t.isInterrupted() 查询打断标志位是否被设置(是不是曾经被打断过)
    public static boolean interrupted()  //Thread.interrupted() 查看“当前”线程是否被打断,如果被打断,恢复标志位( 自动设回false )
    
    • 1
    • 2
    • 3
    • 4
    1. interrupt() :实例方法,设置线程中断标志(打扰一下,你该处理一下中断)
    2. isInterrupted():实例方法,有没有人打扰我?
    3. interrupted():静态方法,有没有人打扰我(当前线程)?复位!

    【总结】:
    interrupt—————设标志位
    isInterrupted———查标志位。
    interrupted————查标志位 并 重置。

    【 interrupt & isInterrupted 】:

    /**
     * interrupt()与isInterrupted()
     * 设置标志位 + 查询标志位
     */
    public class T05_Interrupt_and_isInterrupted {
        public static void main(String[] args) {
            Thread t = new Thread(() -> {
                for (; ; ) {
                    if (Thread.currentThread().isInterrupted()) {
                        System.out.println("Thread is interrupted!");
                        System.out.println(Thread.currentThread().isInterrupted());
                        break;
                    }
                }
            });
    
            t.start();
    
            SleepHelper.sleepSeconds(2);
    
            t.interrupt(); //两秒钟之后设置中断标志位。
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    【最终输出】:

    【线程结束的方案】:
    我这个线程里面会隔一段儿时间 , 我就去检查一下有没有设置过我的标志位,如果被设置了,那么,我就可以让线程结束。

    【 Interrupt & interrupted 】:

    /**
     * interrupt与interrupted()
     */
    public class T06_Interrupt_and_interrupted {
        public static void main(String[] args) {
            Thread t = new Thread(() -> {
                for (; ; ) {
                    if (Thread.interrupted()) {
                        System.out.println("Thread is interrupted!");
                        System.out.println(Thread.interrupted());
                    }
                }
            });
    
            t.start();
    
            SleepHelper.sleepSeconds(2);
    
            t.interrupt();
    
            //思考一下,如果在这里写
            System.out.println("main: " + t.interrupted());  //在这里访问的时候,当前线程是主线程 Main。
            //interrupted这个方法是静态成员变量,永远拿的都是当前线程。
            //输出的是哪个线程的中断状态
        }
    }
    
    • 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

    【 interrupt & sleep 】:

    /**
     * interrupt与sleep() wait() join()
     */
    public class T07_Interrupt_and_sleep {
        public static void main(String[] args) {
            Thread t = new Thread(() -> {
                try {
                    Thread.sleep(10000);   // 用interrupt打断这三个( sleep、wait、join )的话——会抛出异常( InterruptedException )
                    //你必须对异常进行处理。
                } catch (InterruptedException e) {  //只要catch , 它就会进行复位。
                    //一旦抛出InterruptedException异常 , Java会自动帮你把标志位进行复位。
    
                    System.out.println("Thread is interrupted!");
                    System.out.println(Thread.currentThread().isInterrupted());
                }
            });
    
            t.start();
    
            SleepHelper.sleepSeconds(5);
    
            t.interrupt();  //设中断标志位的时候,这个线程正在sleep 。
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    【最终输出】:
    在这里插入图片描述

    【 interrupt & wait 】:

    /**
     * interrupt与sleep() wait() join()
     */
    public class T08_Interrupt_and_wait {
    
        private static Object o = new Object();
    
        public static void main(String[] args) {
            Thread t = new Thread(() -> {
                synchronized (o) {
                    try {
                        o.wait();
                    } catch (InterruptedException e) {
                        System.out.println("Thread is interrupted!");
                        System.out.println(Thread.currentThread().isInterrupted());
                    }
                }
            });
    
            t.start();
    
            SleepHelper.sleepSeconds(5);
    
            t.interrupt();
        }
    }
    
    • 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

    【最终输出】:
    在这里插入图片描述

    【 Interrupt_and_synchronized 】:

    设置标志位,这一件事情,能否把正在竞争锁的状态给打断?——不会的,不再在这个时候抛异常。

    /**
     * interrupt与sleep() wait() join()
     */
    public class T09_Interrupt_and_sync {
    
        private static Object o = new Object();
    
        public static void main(String[] args) {
            Thread t1 = new Thread(() -> {
                synchronized (o) {  //拿到这把锁~ ~ ~ ! ! !
                    SleepHelper.sleepSeconds(10);  // 10秒内 这把锁归 t1 所有。
                }
            });
    
            t1.start();
    
            SleepHelper.sleepSeconds(1);  //主线程1秒之后启动 t2。
    
            Thread t2 = new Thread(() -> {
                synchronized (o) {
                    //抢锁。
                }
                System.out.println("t2 end!");
            });
    
            t2.start();
    
            SleepHelper.sleepSeconds(1);  
    
            t2.interrupt();
        }
    }
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32

    【最终结果】:
    依然是在8秒之后,打印下图内容( 不会抛异常,也不会干别的 ):
    在这里插入图片描述
    总而言之,锁竞争的过程是不会被interrupt干扰的。

    【 Interrupt_and_lock 】:

    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * interrupt与sleep() wait() join()
     */
    public class T10_Interrupt_and_lock {
    
        private static ReentrantLock lock = new ReentrantLock();
    
        public static void main(String[] args) {
            Thread t1 = new Thread(() -> {
                lock.lock();
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
                System.out.println("t1 end!");
            });
    
            t1.start();
    
            SleepHelper.sleepSeconds(1);
    
    
            Thread t2 = new Thread(() -> {
                lock.lock();
                try {
                } finally {
                    lock.unlock();
                }
                System.out.println("t2 end!");
            });
    
            t2.start();
    
            SleepHelper.sleepSeconds(1);
    
            t2.interrupt();
        }
    }
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    【最终输出】:
    等待十秒左右,输出下图内容:
    在这里插入图片描述
    【总结】:
    如果有一个线程占有了一把锁,并且老是不释放。另外一个线程去申请这把锁的时候,中间过程是干扰不到的。如果想干扰到的话,就要了解synchronized和ReentrantLock的区别了。

    【 Interrupt_and_lockInterruptibly 】:

    如果你想打断一个锁争抢的过程,那么就用——ReentrantLock。

    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * interrupt与lockInterruptibly()
     */
    public class T11_Interrupt_and_lockInterruptibly {
    
        private static ReentrantLock lock = new ReentrantLock();
    
        public static void main(String[] args) {
            Thread t1 = new Thread(() -> {
                lock.lock();
                try {
                    SleepHelper.sleepSeconds(10);
                } finally {
                    lock.unlock();
                }
                System.out.println("t1 end!");
            });
    
            t1.start();
    
            SleepHelper.sleepSeconds(1);
    
    
            Thread t2 = new Thread(() -> {
                System.out.println("t2 start!");
                try {
                    lock.lockInterruptibly();  //允许interrupt去干扰抢锁过程。
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
                System.out.println("t2 end!");
            });
    
            t2.start();
    
            SleepHelper.sleepSeconds(1);
    
            t2.interrupt();
    
        }
    }
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    【最终输出】:
    在这里插入图片描述

    【总结】:

    interrupt和sleep() wait() join()

    sleep()方法在睡眠的时候,不到时间是没有办法叫醒的,这个时候可以用interrupt设置标志位,然后呢必须得catch InterruptedException来进行处理,决定继续睡或者是别的逻辑,(自动进行中断标志复位)

  • 相关阅读:
    Docker使用数据卷自定义镜像Dockerfile
    【讲座笔记】如何在稀烂的数据中做深度学习?
    <电力行业> - 《第1课:电力行业的五大四小》
    【字符串匹配算法】KMP、哈希
    Visual Studio 更新:远程文件管理器
    redis+lua脚本实现接口限流
    前端框架 React中Typecript的使用
    第六章:Property-based Testing and Test Oracles
    华为FAT模式无线AP配置实例
    手写注解框架(一)
  • 原文地址:https://blog.csdn.net/fuyuanduan/article/details/127865237