一、方法 方法名static功能说明注意 run()新线程启动后会 调用的方法,线程之间串行如果在构造 Thread 对象时传递了 Runnable 参数,则 线程启动后会调用 Runnable 中的 run 方法,否则默 认不
一、方法
方法名 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 - 打断状态: falsewait:
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] - 打断状态: falsejoin:
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] - 打断状态: false2. 打断正常运行的线程
打断正常运行的线程, 不会清空打断状态
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 - 打断状态: true3. 打断 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() 清除打断状态
总结:
-
处于sleep、join、wait 状态的线程 使用 interrupt() 会清除打断标记 Thread.currentThread().isInterrupted())
-
处于park和 run 的线程,使用 interrupt()不会清除打断标记 Thread.currentThread().isInterrupted())
-
park线程 调用 interrupt()后,该线程后面再使用的 park会失效,需要使用 Thread.interrupted() 恢复park 为有效
三、结束语
评论区可留言,可私信,可互相交流学习,共同进步,欢迎各位给出意见或评价,本人致力于做到优质文章,希望能有幸拜读各位的建议!
专注品质,热爱生活。