File tree Expand file tree Collapse file tree 12 files changed +484
-1
lines changed
Expand file tree Collapse file tree 12 files changed +484
-1
lines changed Original file line number Diff line number Diff line change 33
44
55## 线程
6- 创造线程
6+ 创建线程的两种方法
7+ 正确启动线程
8+ 正确停止线程
79 ThreadPool
810 ThreadLocal
911
Original file line number Diff line number Diff line change 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+
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 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+ }
You can’t perform that action at this time.
0 commit comments