Skip to content

Commit e3547e7

Browse files
stop thread
1 parent 6e63355 commit e3547e7

12 files changed

+484
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ Java并发编程
33

44

55
## 线程
6-
创造线程
6+
创建线程的两种方法
7+
正确启动线程
8+
正确停止线程
79
ThreadPool
810
ThreadLocal
911

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package stopthread;
2+
3+
/**
4+
* 停止线程总结 错误
5+
*
6+
* @Author: zzStar
7+
* @Date: 10-14-2020 16:25
8+
*/
9+
public class StopThreadSummary {
10+
11+
/**
12+
* 正确停止线程
13+
* -> 使用interrupt来通知,而不是强制 (让被停止的线程本身决定后续工作)
14+
* -> 想停止线程,要请求方、被停止方、子方法被调用者方相互配合
15+
* -> stop/suspend 已废弃,volatile的boolean无法处理长时间阻塞的情况
16+
*/
17+
}
18+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package stopthread.rightway;
2+
3+
/**
4+
* 注意 ->
5+
* 如果while里面放try/catch,会导致中断失效
6+
*
7+
* 因为sleep设计时一旦响应中断,就会把线程interrupt标记位为清除
8+
*
9+
* @Author: zzStar
10+
* @Date: 10-14-2020 17:10
11+
*/
12+
public class CantInterrupt {
13+
public static void main(String[] args) throws InterruptedException {
14+
Runnable runnable = () -> {
15+
int num = 0;
16+
//补充中断也效果
17+
while (num <= 10000 && !Thread.currentThread().isInterrupted()) {
18+
if (num % 100 == 0) {
19+
System.out.println(num + "是100的倍数");
20+
}
21+
num++;
22+
//程序将会继续运行
23+
try {
24+
Thread.sleep(10);
25+
} catch (InterruptedException e) {
26+
e.printStackTrace();
27+
}
28+
}
29+
};
30+
Thread thread = new Thread(runnable);
31+
thread.start();
32+
Thread.sleep(500);
33+
thread.interrupt();
34+
}
35+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package stopthread.rightway;
2+
3+
/**
4+
* 生产实践中,停止线程的最佳方法
5+
* -> catch了InterruptedException之后优先选择 ->在方法签名中抛出异常
6+
* 那么在run()就会强制try/catch,且只有try这个方法,因为run方法为顶层函数,无法抛出checked Exception
7+
*
8+
* @Author: zzStar
9+
* @Date: 10-14-2020 17:26
10+
*/
11+
public class RightWayStopThreadInProd implements Runnable {
12+
13+
@Override
14+
public void run() {
15+
while (!Thread.currentThread().isInterrupted()) {
16+
System.out.println("gogogo");
17+
try {
18+
throwInMethod();
19+
} catch (InterruptedException e) {
20+
System.out.println("正确响应处理中断请求");
21+
e.printStackTrace();
22+
}
23+
}
24+
}
25+
26+
private void throwInMethod() throws InterruptedException {
27+
//这里抛出
28+
Thread.sleep(1000);
29+
}
30+
31+
public static void main(String[] args) throws InterruptedException {
32+
Thread thread = new Thread(new RightWayStopThreadInProd());
33+
thread.start();
34+
Thread.sleep(1000);
35+
thread.interrupt();
36+
}
37+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package stopthread.rightway;
2+
3+
/**
4+
* @Description: 在catch子语句中调用Thread.currentThread().interrupt()来恢复设置中断状态,以便在后续的执行中
5+
* 依然能够检查到刚才发生了中断
6+
* @Author: zzStar
7+
* @Date: 2020/10/14 17:47
8+
*/
9+
public class RightWayStopThreadInProdSecond implements Runnable {
10+
11+
@Override
12+
public void run() {
13+
while (true) {
14+
if (Thread.currentThread().isInterrupted()) {
15+
System.out.println("Interrupted,程序运行结束🔚");
16+
break;
17+
}
18+
reInterrupt();
19+
}
20+
}
21+
22+
private void reInterrupt() {
23+
try {
24+
Thread.sleep(1000);
25+
} catch (InterruptedException e) {
26+
//没有这个调用run方法里不会打印出,无法感知中断
27+
Thread.currentThread().interrupt();
28+
e.printStackTrace();
29+
}
30+
}
31+
32+
public static void main(String[] args) throws InterruptedException {
33+
Thread thread = new Thread(new RightWayStopThreadInProdSecond());
34+
thread.start();
35+
Thread.sleep(1000);
36+
thread.interrupt();
37+
}
38+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package stopthread.rightway;
2+
3+
/**
4+
* 带有sleep中断线程的写法
5+
*
6+
* @Author: zzStar
7+
* @Date: 10-14-2020 16:51
8+
*/
9+
public class RightWayStopThreadWithSleep {
10+
11+
public static void main(String[] args) throws InterruptedException {
12+
Runnable runnable = () -> {
13+
int num = 0;
14+
try {
15+
while (num <= 300 && !Thread.currentThread().isInterrupted()) {
16+
if (num % 100 == 0) {
17+
System.out.println(num + "是100的倍数");
18+
}
19+
num++;
20+
}
21+
Thread.sleep(1000);
22+
} catch (InterruptedException e) {
23+
e.printStackTrace();//java.lang.InterruptedException: sleep interrupted
24+
}
25+
};
26+
Thread thread = new Thread(runnable);
27+
thread.start();
28+
Thread.sleep(500);
29+
thread.interrupt();
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package stopthread.rightway;
2+
3+
/**
4+
* 线程在每次迭代后都阻塞,也即每次循环都会调用sleep或wait方法,则不需要每次迭代都检查是否已中断
5+
*
6+
* @Author: zzStar
7+
* @Date: 10-14-2020 17:02
8+
*/
9+
public class RightWayStopThreadWithSleepEveryLoop {
10+
public static void main(String[] args) throws InterruptedException {
11+
Runnable runnable = () -> {
12+
int num = 0;
13+
try {
14+
//这里无需在要一个判断
15+
while (num <= 3000) {
16+
if (num % 100 == 0) {
17+
System.out.println(num + "是100的倍数");
18+
}
19+
num++;
20+
Thread.sleep(100);
21+
}
22+
} catch (InterruptedException e) {
23+
e.printStackTrace();//java.lang.InterruptedException: sleep interrupted
24+
}
25+
};
26+
Thread thread = new Thread(runnable);
27+
thread.start();
28+
Thread.sleep(500);
29+
thread.interrupt();
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package stopthread.rightway;
2+
3+
import static java.lang.Integer.MAX_VALUE;
4+
5+
/**
6+
* run方法内没有sleep或wait方法时,停止线程
7+
*
8+
* @Author: zzStar
9+
* @Date: 10-14-2020 16:37
10+
*/
11+
public class RightWayStopThreadWithoutSleep implements Runnable {
12+
13+
@Override
14+
public void run() {
15+
int num = 0;
16+
while (!Thread.currentThread().isInterrupted() && num <= MAX_VALUE / 2) {
17+
if (num % 10000 == 0) {
18+
System.out.println(num + "是10000的倍数");
19+
}
20+
num++;
21+
}
22+
System.out.println("任务结束了");
23+
}
24+
25+
public static void main(String[] args) throws InterruptedException {
26+
Thread thread = new Thread(new RightWayStopThreadWithoutSleep());
27+
thread.start();
28+
Thread.sleep(1000);
29+
Thread.interrupted();
30+
}
31+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package stopthread.wrongway;
2+
3+
/**
4+
* 错误地停止线程stop(),会导致线程运行一半突然停止,没办法完成一个基本单位地操作
5+
* 造成脏数据
6+
* <p>
7+
* 注意!
8+
* 因为stop本质上是不安全的,停止线程会导致它解锁!已锁定的所有监视器,
9+
* 如果先前受这些监视器保护的任何对象处于不一致状态,则其他线程现在可以以不一致的状态查看这些对象
10+
*
11+
* @Author: zzStar
12+
* @Date: 10-15-2020 16:35
13+
*/
14+
public class StopThread implements Runnable {
15+
@Override
16+
public void run() {
17+
//5个联队
18+
for (int i = 0; i < 5; i++) {
19+
System.out.println("连队" + i + "领取武器");
20+
//每个连队10个人
21+
for (int j = 0; j < 10; j++) {
22+
System.out.println(j);
23+
try {
24+
Thread.sleep(50);
25+
} catch (InterruptedException e) {
26+
e.printStackTrace();
27+
}
28+
}
29+
System.out.println("连队" + i + "已经领取完毕");
30+
}
31+
}
32+
33+
public static void main(String[] args) {
34+
Thread thread = new Thread(new StopThread());
35+
thread.start();
36+
try {
37+
Thread.sleep(1000);
38+
} catch (InterruptedException e) {
39+
e.printStackTrace();
40+
}
41+
/*
42+
thread.stop();
43+
//suspend会让一个线程挂起,在恢复之前锁不会释放,也就是带着锁休息,易造成死锁
44+
thread.suspend();
45+
thread.resume();
46+
*/
47+
}
48+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package stopthread.wrongway;
2+
3+
/**
4+
* 演示Volatile的局限 -> part1 看似可行
5+
*
6+
* @Author: zzStar
7+
* @Date: 10-15-2020 16:52
8+
*/
9+
public class WrongWayVolatile implements Runnable {
10+
//可见性
11+
private volatile boolean canceled = false;
12+
13+
@Override
14+
public void run() {
15+
int num = 0;
16+
try {
17+
while (num <= 10000 && !canceled) {
18+
if (num % 100 == 0) {
19+
System.out.println(num + "是100的倍数");
20+
}
21+
num++;
22+
Thread.sleep(1);
23+
}
24+
} catch (InterruptedException e) {
25+
e.printStackTrace();
26+
}
27+
}
28+
29+
public static void main(String[] args) {
30+
WrongWayVolatile wrongWayVolatile = new WrongWayVolatile();
31+
Thread thread = new Thread(wrongWayVolatile);
32+
thread.start();
33+
try {
34+
//使当前线程休眠,进入阻塞状态(暂停执行)
35+
Thread.sleep(3000);
36+
} catch (InterruptedException e) {
37+
e.printStackTrace();
38+
}
39+
wrongWayVolatile.canceled = true;
40+
}
41+
}

0 commit comments

Comments
 (0)