多线程
5 线程状态
- 线程的五大状态:创建状态、就绪状态、阻塞状态、运行状态、死亡状态。如下图所示:
具体解释如下:
- 线程方法:
5.1 停止线程
- 不推荐使用JDK提供的stop()方法、destroy()方法【已废弃 – deprecated】
- 推荐线程自己正常停止
- 建议使用一个标志位进行终止变量:当
flag = false
,则终止线程运行
package com.duo.state;//测试stop
//1.建议线程正常停止 --- 利用循环次数,不建议死循环
//2.建议使用标志位 --- 主动设置一个标志位
//3.不要使用stop()、destroy()等deprecated方法public class StopTest implements Runnable {//1.先设置一个标志位private boolean flag = true;@Overridepublic void run() {int i = 0;while (flag) {System.out.println("run...Thread " + i++);}}//2.设置一个公开的方法以停止线程,转换标志位public void myStop() {this.flag = false;}public static void main(String[] args) {StopTest stopTest = new StopTest();new Thread(stopTest).start();for (int i = 0; i < 1000; i++) {System.out.println("main() " + i);if (i == 499) {stopTest.myStop();System.out.println("线程即将停止");}}}}
运行结果:
可以发现,在i == 49
时,通过调用转换标志位的停止线程方法myStop() {}
,”线程即将停止”,并在此后未有“run…Thread ii”语句输出,即线程已停止。
5.2 线程休眠
- sleep()括号中指定当前线程阻塞的毫秒数
- sleep存在异常InterruptedException
- sleep时间达到后,线程进入就绪状态
- sleep可以模拟网络延时、倒计时等
- 每一个对象都有一个锁,sleep不会释放锁
这里还以之前抢火车票的代码为例:
package com.duo.state;//模拟网络延时:放大问题的发生性
public class SleepTest implements Runnable {private int ticketNum = 10;@Overridepublic void run() {while (ticketNum > 0) {//模拟延时try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "->抢到了第" + ticketNum-- + "张票");}}public static void main(String[] args) {SleepTest ticket = new SleepTest();new Thread(ticket, "ming").start();new Thread(ticket, "hua").start();new Thread(ticket, "hong").start();}
}
运行结果:
可以发现,此时代码中的线程是不安全的,即多个线程操作了同一对象。(将会在之后加以修正改善)
下面模拟一个倒计时:
package com.duo.state;//模拟倒计时
public class SleepTest2 {public static void tenCounting() throws InterruptedException {int num = 10;do {Thread.sleep(1000);System.out.println(num--);} while (num > 0);}public static void main(String[] args) {try {tenCounting();} catch (InterruptedException e) {e.printStackTrace();}}
}
运行结果:
其中,10~1的倒计时按照秒数倒数完成打印输出。
还可以通过sleep()打印系统当前时间:
package com.duo.state;import java.text.SimpleDateFormat;
import java.util.Date;//打印系统当前时间
public class SleepTest2 {public static void main(String[] args) {Date date = new Date(System.currentTimeMillis()); //先获取系统当前时间while (true) {try {Thread.sleep(1000);System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));date = new Date(System.currentTimeMillis()); //更新系统当前时间} catch (InterruptedException e) {e.printStackTrace();}}}
}
运行结果: