一、方法
方法名 | 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()
清除打断状态
总结:
-
处于
sleep
、join
、wait
状态的线程 使用interrupt()
会清除打断标记Thread.currentThread().isInterrupted())
-
处于
park
和run
的线程,使用interrupt()
不会清除打断标记Thread.currentThread().isInterrupted())
-
park线程 调用
interrupt()
后,该线程后面再使用的park
会失效,需要使用Thread.interrupted()
恢复park
为有效
三、结束语
评论区可留言,可私信,可互相交流学习,共同进步,欢迎各位给出意见或评价,本人致力于做到优质文章,希望能有幸拜读各位的建议!
标签:状态,java,Thread,park,线程,打断,Test From: https://blog.51cto.com/fyphome/5784636专注品质,热爱生活。