多线程10:线程状态及常见方法

线程状态:
  1. new一个Thread对象时候就处于新生状态了。
  2. 调用start方法,立即进入就绪状态。等待cpu的调度
  3. cpu调度时,进入运行状态。cpu调度谁看心情
  4. 运行时,调用sleep(),wait()或同步锁定时,线程进入阻塞状态,阻塞解除后进入就绪状态
  5. 如果正常执行完毕进入死亡状态。

线程方法:
方法
说明
setPriority(int newPriority) 设置优先级
更改线程的优先级,线程的优先级代表的是概率,范围从1到10,默认为5 。
static void sleep(long millis)休眠
使线程停止运行设定的时间,将处于阻塞状态
void join()插队
等待该线程终止,阻塞指定线程等到另一个线程完成以后再继续执行。
static void yield()礼让
暂停当前正在执行的线程,并执行其他线程
void interrupt()中断
中断线程,别用这个方式
boolean isAlive()是否存活
测试线程是否处于活动状态
1.停止线程:
  • 不推荐使用JDK使用的stop()destroy()方法。
[已废弃]@Deprecated,Ctrl+左键打开Thread类-->Structrue-->找到
  对应方法就能看见以下代码:
 1 @Deprecated
 2 public void destroy() {
 3     throw new NoSuchMethodError();
 4 }
 5 
 6 @Deprecated
 7 public final void stop() {
 8     SecurityManager security = System.getSecurityManager();
 9     if (security != null) {
10         checkAccess();
11         if (this != Thread.currentThread()) {
12             security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
13         }
14     }
15     // A zero status value corresponds to "NEW", it can't change to
16     // not-NEW because we hold the lock.
17     if (threadStatus != 0) {
18         resume(); // Wake up thread if it was suspended; no-op otherwise
19     }
20 
21     // The VM can handle all thread states
22     stop0(new ThreadDeath());
23 }
  • 推荐线程自己停止下来
  • 建议使用一个标志位进行终止变量当flag=false,则终止线程运行。
思路:
  通过一个flag,设立一个外部标志位,然后通过一个公开的方法,我们去调用这个方法,来切换一下标志位,让线程停止
 1 package com.thread.state;
 2 
 3 //测试stop
 4 //1.建议线程正常停止--->利用次数,不建议死循环
 5 //2.建议使用标志位--->设置一个标志位
 6 //3.不要使用stop和的、destroy等过时或者JDK不建议使用的方法
 7 
 8 public class TestStop implements Runnable {
 9 
10     //1.设置一个标志位
11     private boolean flag = true;
12 
13     @Override
14     public void run() {
15         int i = 0;
16         while (flag) {
17             System.out.println("run...Thread" + i++);
18         }
19     }
20 
21     //2.设置一个公开的方法停止线程,换标志位
22 
23     public void stop() {
24         this.flag = false;
25     }
26 
27     public static void main(String[] args) {
28         TestStop testStop = new TestStop();
29         new Thread(testStop).start();
30 
31         for (int i = 0; i < 1000; i++) {
32             System.out.println("main" + i);
33             if (i == 900) {
34                 //调用自己写的stop方法切换标志位,让线程停止
35                 testStop.stop();
36                 System.out.println("线程该停止了");
37             }
38         }
39 
40     }
41     
42 }
2.线程休眠:
  • sleep(时间)指定当前线程阻塞的毫秒数
  • sleep存在异常InterrruptedException
  • sleep时间达到后线程进入就绪状态
  • sleep可以模拟网络延时,倒计时等
  • 每一个对象都有一个锁,sleep不会释放锁
案例一:模拟网络延时:放大问题的发生性
 1 package com.thread.state;
 2 
 3 //模拟网络延时:放大问题的发生性
 4 public class TestSleep implements Runnable {
 5 
 6     //票数
 7     private int ticketNums = 10;
 8 
 9     @Override
10     public void run() {
11         while (true) {
12             if (ticketNums <= 0) {
13                 break;
14             }
15             //模拟延时
16             try {
17                 Thread.sleep(100);
18             } catch (InterruptedException e) {
19                 e.printStackTrace();
20             }
21 
22             System.out.println(Thread.currentThread().getName() + "-->拿到了" + ticketNums-- + "票");
23         }
24     }
25 
26     public static void main(String[] args) {
27 
28         TestSleep ticket = new TestSleep();
29 
30         new Thread(ticket, "小红").start();
31         new Thread(ticket, "老师").start();
32         new Thread(ticket, "黄牛").start();
33     }
34 
35 }
案例二:模拟倒计时
 1 package com.thread.state;
 2 
 3 //模拟倒计时
 4 public class TestSleep2 {
 5 
 6     public static void main(String[] args) {
 7         try {
 8             tenDown();
 9         } catch (InterruptedException e) {
10             e.printStackTrace();
11         }
12 
13     }
14 
15     //模拟倒计时
16     public static void tenDown() throws InterruptedException {
17         int num = 10;
18 
19         while (true) {
20             Thread.sleep(1000);
21             System.out.println(num--);
22             if (num <= 0) {
23                 break;
24             }
25         }
26     }
27 }
案例三:打印系统当前时间
 1 package com.thread.status;
 2 
 3 import java.text.SimpleDateFormat;
 4 import java.util.Date;
 5 
 6 //模拟倒计时
 7 public class TestSleep2 {
 8 
 9     public static void main(String[] args) {
10         //打印当前系统时间
11         Date startTime = new Date(System.currentTimeMillis());//获取系统当前时间
12 
13         while (true) {
14             try {
15                 Thread.sleep(1000);
16                 System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
17                 startTime = new Date(System.currentTimeMillis());//更新当前时间
18             } catch (InterruptedException e) {
19                 e.printStackTrace();
20             }
21         }
22     }
23 }
24 结果:
25 17:28:27
26 17:28:28
27 17:28:29
28 17:28:30
29 17:28:31
30 ...
3.线程礼让:
  • 礼让线程,让当前正在执行的线程暂停,但不阻塞
  • 将线程从运行状态转为就绪状态
  • 让cpu重新调度,礼让不一定成功!看cpu心情
 1 package com.thread.state;
 2 
 3 //测试礼让线程
 4 //礼让不一定成功,看cpu心情
 5 public class TestYield {
 6 
 7     public static void main(String[] args) {
 8         MyYield myYield = new MyYield();
 9 
10         new Thread(myYield, "a").start();
11         new Thread(myYield, "b").start();
12 
13     }
14 }
15 
16 class MyYield implements Runnable {
17 
18     @Override
19     public void run() {
20         System.out.println(Thread.currentThread().getName() + "线程开始执行");
21         Thread.yield();//礼让
22         System.out.println(Thread.currentThread().getName() + "线程停止执行");
23     }
24 }
25 
26 结果:
27 b线程开始执行
28 a线程开始执行
29 b线程停止执行
30 a线程停止执行    礼让成功
31 
32 a线程开始执行
33 a线程停止执行
34 b线程开始执行
35 b线程停止执行    礼让失败,线程正常结束
4.Join合并线程:
  • Join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞
  • 可以想象成插队
 1 package com.thread.state;
 2 
 3 //测试Join方法-->想象为插队
 4 public class TestJoin implements Runnable {
 5 
 6     @Override
 7     public void run() {
 8         for (int i = 0; i < 1000; i++) {
 9             System.out.println("线程vip来了" + i);
10         }
11     }
12 
13     public static void main(String[] args) throws InterruptedException {
14 
15         //启动我们的线程
16         TestJoin testJoin = new TestJoin();
17         Thread thread = new Thread(testJoin);
18         thread.start();
19 
20 
21         //主线程
22         for (int i = 0; i < 500; i++) {
23             if (i == 200) {
24                 thread.join();//插队
25             }
26             System.out.println("main" + i);
27         }
28 
29     }
30 }
5.线程状态观测:查看JDK帮助文档
public static enum Thread.State extends Eunm<Thread.State>
线程状态。线程可以处于以下状态之一
  • NEW
    • 尚未启动的线程处于此状态。
  • RUNNABLE
    • 在Java虚拟机中运行的线程处于此状态。
  • BLOCKED
    • 被阻塞等待监视器锁定的线程处于此状态。
  • WAITING
    • 正在等待另一个线程执行特定动作的线程。
  • TIMED_WAITING
    • 正在等待另一个线程执行动作达到指定等待时间的线程。
  • TERMINATED
    • 已退出的线程处于此状态。
一个线程可以在给定时间点处于一个状态。这些状态是不反映任何操作系统线程状态的虚拟机状态。
 1 package com.thread.state;
 2 
 3 //观察测试线程状态
 4 public class TestState {
 5 
 6     public static void main(String[] args) throws InterruptedException {
 7         Thread thread = new Thread(() -> {
 8             for (int i = 0; i < 5; i++) {
 9                 try {
10                     Thread.sleep(1000);
11                 } catch (InterruptedException e) {
12                     e.printStackTrace();
13                 }
14             }
15             System.out.println("///////");
16         });
17 
18 
19         //观察状态
20         Thread.State state = thread.getState();
21         System.out.println(state);//NEW
22 
23         //观察启动后
24         thread.start();//启动线程
25         state = thread.getState();
26         System.out.println(state);//RUNNABLE
27 
28         while (state != Thread.State.TERMINATED) {//只要线程不终止,就一直输出状态
29             Thread.sleep(100);
30             state = thread.getState();//更新线程状态
31             System.out.println(state);//输出状态
32         }
33     }
34 }
35 
36 结果:
37 NEW
38 RUNNABLE
39 TIMED_WAITING
40 TIMED_WAITING
41 TIMED_WAITING
42 TIMED_WAITING
43 TIMED_WAITING
44 TIMED_WAITING
45 TIMED_WAITING
46 TIMED_WAITING
47 TIMED_WAITING
48 TIMED_WAITING
49 TIMED_WAITING
50 TIMED_WAITING
51 TIMED_WAITING
52 TIMED_WAITING
53 TIMED_WAITING
54 TIMED_WAITING
55 TIMED_WAITING
56 TIMED_WAITING
57 TIMED_WAITING
58 TIMED_WAITING
59 TIMED_WAITING
60 TIMED_WAITING
61 TIMED_WAITING
62 TIMED_WAITING
63 TIMED_WAITING
64 TIMED_WAITING
65 TIMED_WAITING
66 TIMED_WAITING
67 TIMED_WAITING
68 TIMED_WAITING
69 TIMED_WAITING
70 TIMED_WAITING
71 TIMED_WAITING
72 TIMED_WAITING
73 TIMED_WAITING
74 TIMED_WAITING
75 TIMED_WAITING
76 TIMED_WAITING
77 TIMED_WAITING
78 TIMED_WAITING
79 TIMED_WAITING
80 TIMED_WAITING
81 TIMED_WAITING
82 TIMED_WAITING
83 TIMED_WAITING
84 ///////
85 TERMINATED
86 
87 Process finished with exit code 0
88 新生进入NEW状态, start启动后进入RUNNABLE状态,休眠1秒进入WAITING状态每隔100ms
89 更新一次状态,最后结束后输出一句话//////,最终进入TERMINATED状态

 

posted @ 2020-02-04 18:52  断浮  阅读(257)  评论(0编辑  收藏  举报