首页 > 其他分享 >各种线程状态的打断方法

各种线程状态的打断方法

时间:2022-10-21 23:02:21浏览次数:60  
标签:状态 java Thread park 线程 打断 Test

一、方法

方法名 static 功能说明 注意
run() 新线程启动后会 调用的方法,线程之间串行 如果在构造 Thread 对象时传递了 Runnable 参数,则 线程启动后会调用 Runnable 中的 run 方法,否则默 认不执行任何操作。但可以创建 Thread 的子类对象, 来覆盖默认行为
join() 等待线程运行结束
join(long n) 等待线程运行结 束,最多等待 n 毫秒
isInterrupted() 判断是否被打 断, 不会清除 打断标记
interrupt() 打断线程 如果被打断线程正在 sleep,wait,join 会导致被打断 的线程抛出 InterruptedException,并清除 ;如果打断的正在运行的线程,不会清除 ;park 的线程被打断,也会设置 打断标记,不会清除
interrupted() static 判断当前线程是 否被打断 会清除 打断标记
currentThread() static 获取当前正在执 行的线程
sleep(long n) static 让当前执行的线 程休眠n毫秒, 休眠时让出 cpu 的时间片给其它 线程

二、使用

1. 打断 sleep,wait,join 的线程

这几个方法都会让线程进入阻塞状态 打断 sleep 的线程, 会清空打断状态,以 sleep 为例

Thread t1 = new Thread(()-> {
    //sleep(1);
    
    //try {
    //    Thread.currentThread().join();
    //} catch (InterruptedException e) {
    //    e.printStackTrace();
    //}
    
    try {
        Thread.currentThread().wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    
}, "t1");
t1.start();
sleep(0.5);
t1.interrupt();
log.debug(" 打断状态: {}", t1.isInterrupted());

输出

sleep:

java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at cn.itcast.n2.util.Sleeper.sleep(Sleeper.java:8)
at cn.itcast.n4.TestInterrupt.lambda$test1$3(TestInterrupt.java:59)
at java.lang.Thread.run(Thread.java:745)
21:18:10.374 [main] c.TestInterrupt - 打断状态: false

wait:

Exception in thread "t1" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at cn.itcast.test.Test.lambda$main$0(Test.java:30)
	at java.lang.Thread.run(Thread.java:748)
15:37:32.974 c.Test [main] -  打断状态: false

join:

java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at java.lang.Thread.join(Thread.java:1252)
	at java.lang.Thread.join(Thread.java:1326)
	at cn.itcast.test.Test.lambda$main$0(Test.java:25)
	at java.lang.Thread.run(Thread.java:748)
15:46:22.178 c.Test [main] -  打断状态: false

2. 打断正常运行的线程

打断正常运行的线程, 不会清空打断状态

private static void test2() throws InterruptedException {
    Thread t2 = new Thread(()->{
        while(true) {
            Thread current = Thread.currentThread();
            boolean interrupted = current.isInterrupted();
            if(interrupted) {
                log.debug(" 打断状态: {}", interrupted);
                break;
            }
    	}
    }, "t2");
    t2.start();
    sleep(0.5);
    t2.interrupt();
}  

输出

20:57:37.964 [t2] c.TestInterrupt - 打断状态: true  

3. 打断 park 线程

打断 park 线程, 不会清空打断状态

private static void test3() throws InterruptedException {
    Thread t1 = new Thread(() -> {
        log.debug("park...");
        LockSupport.park();
        log.debug("unpark...");
        log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
    }, "t1");
    t1.start();
    sleep(0.5);
    t1.interrupt();
}

输出

21:11:52.795 [t1] c.TestInterrupt - park...
21:11:53.295 [t1] c.TestInterrupt - unpark...
21:11:53.295 [t1] c.TestInterrupt - 打断状态:true

如果打断标记已经是 true, 则 park 会失效

private static void test4() {
    Thread t1 = new Thread(() -> {
        for (int i = 0; i < 5; i++) {
            log.debug("park...");
            LockSupport.park();
            log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
        }
        // 清除 打断标记,即 设置为 false
        Thread.interrupted();
        log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
        log.debug("park...");
        LockSupport.park();
        log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
    });
    t1.start();
    sleep(1);
    t1.interrupt();
}

输出

15:54:57.684 c.Test [Thread-0] - park...
15:54:58.692 c.Test [Thread-0] - 打断状态:true
15:54:58.696 c.Test [Thread-0] - park...
15:54:58.696 c.Test [Thread-0] - 打断状态:true
15:54:58.696 c.Test [Thread-0] - park...
15:54:58.696 c.Test [Thread-0] - 打断状态:true
15:54:58.696 c.Test [Thread-0] - park...
15:54:58.696 c.Test [Thread-0] - 打断状态:true
15:54:58.696 c.Test [Thread-0] - park...
15:54:58.696 c.Test [Thread-0] - 打断状态:true
15:54:58.696 c.Test [Thread-0] - 打断状态:false
15:54:58.696 c.Test [Thread-0] - park...
# 还有 下一句打断标记没打印出来,此时已恢复 park 功能

提示 可以使用 Thread.interrupted() 清除打断状态

总结:

  • 处于sleepjoinwait 状态的线程 使用 interrupt() 会清除打断标记 Thread.currentThread().isInterrupted())

  • 处于parkrun 的线程,使用 interrupt()不会清除打断标记 Thread.currentThread().isInterrupted())

  • park线程 调用 interrupt()后,该线程后面再使用的 park会失效,需要使用 Thread.interrupted() 恢复park 为有效

三、结束语

评论区可留言,可私信,可互相交流学习,共同进步,欢迎各位给出意见或评价,本人致力于做到优质文章,希望能有幸拜读各位的建议!

专注品质,热爱生活。

标签:状态,java,Thread,park,线程,打断,Test
From: https://blog.51cto.com/fyphome/5784636

相关文章

  • 进程与线程的区别
    简单介绍一、线程的基本概念线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少......
  • 进程与线程的区别
    进程是操作系统分配资源的基本单位,而线程是操作系统调度的基本单位。一个进程中至少包含一个线程,线程不能独立于进程而存在。进程不能共享资源,而线程可以。线程可以看作是......
  • 线程和进程的区别
    一、进程和线程的概念 进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。 线程:是进程的一个执行单元,是进程......
  • 进程与线程的区别
    进程资源分配的最小单位。计算机的核心是cpu,进程和线程都是一个时间段的描述,是CPU工作时间段的描述。我们打开浏览器,实际上就是打开了一个进程,它就会被载入内存空间,并在......
  • 进程与线程的区别
    1、首先是定义进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程。进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统中的并发执行的单......
  • 多线程基础知识
    【单核处理器和多核处理器的多线程】单核处理器:为每个线程分配时间片。来模拟并发多核处理器:一核一线程,真正实现并发 【标志】线程一致性,IsAlive就为true,否则为fals......
  • 多线程技术总结
    csdn上笔记也多,但是用的不多,不用就忘了。博客线程笔记——技术笔记:.Net全套就业班视频教程在多线程中的跨线程的方法调用就得用委托。一个进程的多个线程间可相互......
  • Linux 进程与线程、线程与信号
    进程与线程多线程程序调用fork后,子进程只是调用fork线程的完整复制。子进程自动继承父进程种互斥锁的状态。这引起一个问题:子进程不知道从父进程继承来的互斥锁的具体状态......
  • 进程和线程的区别
    一:什么是线程:线程是操作系统能够进行运算调度的最小单元。它被包含在进程中,是进程中实际运行的单位。一个进程中可以并发多个线程,每个线程执行不同的任务。二;什么是进......
  • java 线程详解
    线程目录HelloWorld在Java中有两种方式创建线程,第一种方式是实现​​Runnable​​​接口,第二种方式是继承​​Thread​​类,下面是使用示例:publicclassRunnableDe......