首页 > 其他分享 >线程的打断

线程的打断

时间:2023-10-15 16:44:23浏览次数:53  
标签:log Thread 标记 t1 线程 打断

每个线程上都会有一个打断标记,默认是false,当别的线程打断某个线程后打断标记就会变为true。

打断机制提供了一种让线程1更友好的去结束别的线程的方式: 线程1打断线程2相当于给线程2发了一个信号,

线程2自己决定收到这个信号时要做的处理。

一、打断相关的方法

和打断相关的方法有如下几个

1.1 实例方法interrupt

Thread类中的实例方法java.lang.Thread#interrupt,用来打断一个线程,例如t1.interrupt() 会把正常运行的线程t1的打断标记变为true

1.2 实例方法isInterrupted

Thread类中的实例方法java.lang.Thread#isInterrupted() ,返回线程的打断标记值

1.3 静态方法interrupted

Thread类中的静态方法 java.lang.Thread#interrupted,返回当前线程的打断标记值并清空打断状态,

也就是说哪个线程的代码中调用了此方法,就返回打断状态,并且如果打断状态是true还会把它变成false。

@Slf4j
public class ThreadTest3 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    log.info("打断状态: {}",Thread.currentThread().isInterrupted());
                    if(Thread.interrupted()) {//标记是true时才会进if,因为这方法会清空打断标记,
                        //所以内部再次获取打断标记值为false
                        log.info("被打断了,调用Thread.interrupted()后的打断状态: {}",Thread.currentThread().isInterrupted());
                        break;
                    }
                }
            }
        });
        t1.start();
        Thread.sleep(2000);
        t1.interrupt();//打断t1
    }
}

二、打断正常运行的线程

打断正常运行的线程仅会修改被打断线程的打断标记,不会影响线程的运行,需要被打断线程自己来处理被打断后的逻辑,像上边1.3中案例一样。

三、打断阻塞状态的线程

3.1 打断调用sleep,wait方法后陷入阻塞的线程

sleep,wait方法被打断时会抛出InterruptedException 异常,同时会清空打断标记,也就是这时获取打断标记得到的是false。

@Slf4j
public class ThreadTest3 {


    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //先获取锁,然后调用wait方法阻塞
                synchronized (ThreadTest3.class) {
                    try {
                        log.info("t1运行");
                        //在锁对象上调用wait方法阻塞
                        ThreadTest3.class.wait();
                    } catch (InterruptedException e) {
                        //被打断后会抛出InterruptedException
                        e.printStackTrace();
                        //并且会清空打断标记,也就是这时获取打断标记得到的是false,
                        log.info("获取打断标记:{}",Thread.currentThread().isInterrupted());
                    }
                }
            }
        });
        t1.start();
        Thread.sleep(2000);
        t1.interrupt();//打断t1
    }
}

3.2打断调用LockSupport.park()进入阻塞的线程

打断调用LockSupport.park()进入阻塞的线程,会使用这个线程恢复运行,并且打断标记的值会是true,

但要注意的是在打断标记是true的情况下再次调用park方法并不能使线程进入阻塞状态,只有清空打断标记后才能重新park线程到阻塞状态。

public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                log.info("t1 run");
                LockSupport.park();
                log.info("t1 after park1,打断标记: {}",Thread.currentThread().isInterrupted());
                //第一次打断后在打断标记是true的情况下再次park不起作用,
                LockSupport.park();
                log.info("t1 after park2");
                log.info("先获取再清空打断标记:{}",Thread.interrupted());//这个方法会先获取打断标记再清空打断标记
                LockSupport.park();//现在就可以park住线程使其进入阻塞状态了
                log.info("t1 after park3");

            }
        });
        t1.start();
        Thread.sleep(2000);
        t1.interrupt();//打断t1
    }

标签:log,Thread,标记,t1,线程,打断
From: https://www.cnblogs.com/chengxuxiaoyuan/p/17765781.html

相关文章

  • 经典多线程题目
    1.三种线程按顺序执行publicclassTest1{//privatestaticLoggerlog=Logger.getLogger(Test2.class);publicstaticvoidmain(String[]args)throwsInterruptedException{//创建三个线程按照线程a,b,c执行Threada=newPrintThread()......
  • 线程操作控件
    privatevoidForm1_Load(objectsender,EventArgse){System.Threading.Threadthread=newSystem.Threading.Thread(CrossThreadFlush);thread.IsBackground=true;thread.Start();}privat......
  • ArrayList线程安全问题分析
    测试代码:importjava.util.ArrayList;publicclassTestThreadSafe{staticfinalintLOOP_NUM=10;publicstaticvoidmain(String[]args)throwsInterruptedException{ThreadSafeSubClasstest=newThreadSafeSubClass();test.method1(......
  • 锁+多线程
     互斥锁mutex:保证共享数据操作的完整性,保证在任一时刻只能有一个线程访问对象。锁有两个操作。一个P操作(上锁),一个V操作(解锁)。P和V都是原子操作,就是在执行P和V操作时,不会被插队。锁一般使用信号量来实现的,mutex其实就是信号量=1。互斥量就是同一时间能够分给一个人,即S=1。S=......
  • python多线程with方式加锁
    python多线程with方式加锁"""pythonTreading中的Lock模块提供了加锁和释放锁的方法,分别是acquire()和release().这两个方法可以搭配python的with语句使用."""#示例fromthreadingimportLock​temp_lock=Lock()​withtemp_lock: print(temp_lock) #输出是<locked......
  • Java程序的main主线程的运行过程
    在Java虚拟机进程中,执行程序代码的任务是由线程来完成的。每当用java命令启动一个Java虚拟机进程,Java虚拟机就会创建并启动一个main主线程,该线程从程序入口main()方法开始执行。main主线程执行main()方法下面以例程1的Sample为例,介绍线程的运行过程。例程1 Sample.javapublicclas......
  • 并发编程-4.用户界面响应能力和线程
    利用后台线程在第一章中,我们学习了如何创建后台线程并讨论了它们的一些用途。后台线程的优先级低于进程的主线程和其他线程池线程。此外,活动的后台线程不会阻止用户或系统终止应用程序。这意味着后台线程非常适合执行以下任务:•写入日志和分析数据•监控网络或文件系统资源......
  • SimpleDateFormat线程安全性
    SimpleDateFormat线程安全性0结论SimpleDateFormat是线程不安全的。在JDK中关于SimpleDateFormat有这样一段描述:Dateformatsarenotsynchronized.Itisrecommendedtocreateseparateformatinstancesforeachthread.Ifmultiplethreadsaccessaformatconcurr......
  • 并行编程-1.托管线程概念
    .NET线程基础知识是时候开始学习C#和.NET中的线程基础知识了。我们将介绍.NET6中可用的托管线程概念,但其中许多功能从一开始就是.NET的一部分。System.Threading命名空间从.NETFramework1.0开始可用。在随后的20年中,为开发人员添加了许多有用的功能。为了在......
  • 多线程逆向
    一.资料检索以及归纳XDBG调试时默认是只运行下断调试的线程其它线程处于暂停挂起状态属于单线程调试。打开线程窗口可以查看线程挂起计数(+号-号快捷键可以挂起恢复线程)双击线程可进入选择线程,如果要调试指定线程的话我的理解是应该在线程代码中下断(线程的各种系统CALL),线程会自......