线程共有五大状态
1 创建
线程对象被创建就进入到新状态(new)
2 就绪
调用线程的start()方法,线程进入就绪状态
3 运行
线程进入运行状态,开始执行线程体代码
4 阻塞
调用sleep,wait等方法时,线程进入阻塞状态,线程不再继续往下执行,阻塞事件解除后,重新进入就绪状态,等待cpu调度执行
5 死亡
线程中断或者结束,一旦进入死亡状态,就不能再次启动线程
线程方法
停止线程
注意:
1 不推荐使用jdk提供的stop(),destroy()方法(已废弃)
2 推荐线程自己停下来
3 建议使用一个标志位进行终止变量,当flag=false时,则终止线程运行
package com.wyh.thread; /** * @program: Thread * @description: 利用flag让线程停止 * @author: 魏一鹤 * @createDate: 2022-01-01 22:38 **/ //测试线程停止 // 注意点 // 1、建议线程正常停止---> 利用次数 不建议死循环(就算是死循环也要定义延时,不要跑的太快卡死cpu) // 2. 建议使用标志位 ---> 设置一个标志位 // 3. 不要使用stop或者destroy等过时或者jdk不建议使用的方法 public class TestThreadStop implements Runnable{ //1.定义一个标识符决定线程是否运行 true为运行 false为停止 private boolean flag=true; @Override public void run() { int i=0; // true为运行 false为停止 while (flag){ System.out.println("run....Thread"+i++); } } //2.定义一个方法转换标识符停止线程 public void stopThread() { //false让线程停止 this.flag=false; } public static void main(String[] args){ //创建线程对象 TestThreadStop testThreadStop = new TestThreadStop(); //开启线程 new Thread(testThreadStop).start(); for (int i = 0; i < 1000; i++) { //主线程跑的次数 System.out.println("main:"+i); if(i==900){ //线程运行900次让线程停止 调用stop方法切换标志位,让线程停止 testThreadStop.stopThread(); System.out.println("线程该停止了"); } } } }
线程休眠 sleep
sleep(时间)指定当前线程阻塞的毫秒数(1000hs(毫秒)=1s(秒),一般一秒就够用)
sleep存在异常interruptedException
sleep时间达到后线程进入就绪状态
sleep可以模拟网络延时,倒计时等
每一个对象都有一个锁,sleep不会释放锁(线程同步)
线程休眠的作用(模拟网络延时): 放大问题的发生性
我们还是拿买票的例子演示
package com.wyh.thread; /** * @program: Thread * @description: 线程休眠(阻塞) 模拟网络延时 * @author: 魏一鹤 * @createDate: 2022-01-02 20:13 **/ //模拟网络延时 //作用 1 放大问题的发生性 public class TestThreadSleep implements Runnable { //票数 int ticketNums=10; @Override public void run() { //火车票抢票 while (true) { //如果没票了就停止 if(ticketNums<=0){ break; } //模拟延迟 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //Thread.currentThread().getName() 获取当前线程名称 我们是可以给线程命名的 System.out.println(Thread.currentThread().getName() + "-->抢到了"+ticketNums--+"张票"); } } public static void main(String[] args){ //创建runnable接口的实现类对象 TestThreadSleep testThreadSleep = new TestThreadSleep(); //3个线程一起去抢票 new Thread(testThreadSleep,"魏一鹤").start(); new Thread(testThreadSleep,"魏一鸣").start(); new Thread(testThreadSleep,"黄牛党").start(); } }
模拟倒计时
package com.wyh.thread; /** * @program: Thread * @description: 模拟倒计时 * @author: 魏一鹤 * @createDate: 2022-01-02 20:22 **/ public class TestThreadSleep2 { //倒计数方法 public static void TimeDown() throws InterruptedException { //初始化秒数 int timeNum=10; while (true){ //线程休眠1s 1000ms=1s Thread.sleep(1000); //自减 System.out.println(timeNum--); //倒到0时候停止 if(timeNum==0){ System.out.println("倒计时结束!"); break; } } } public static void main(String[] args) throws InterruptedException { TimeDown(); } }
每1s获取当前系统时间
package com.wyh.thread; import java.text.Format; import java.text.SimpleDateFormat; import java.util.Date; import java.util.SimpleTimeZone; /** * @program: Thread * @description: 打印当前时间 * @author: 魏一鹤 * @createDate: 2022-01-02 20:32 **/ public class TestThreadSleep3 { //打印当前系统时间 public static void main(String[] args) throws InterruptedException { //获取当前系统时间 Date date = new Date(System.currentTimeMillis()); while (true) { Thread.sleep(1000); System.out.println("当前时间:"+new SimpleDateFormat("HH:mm:ss").format(date)); //更新当前时间 date=new Date(System.currentTimeMillis()); } } }
总结sleep的特点和作用
模拟网络延迟
倒计时
sleep不会释放锁(线程同步)
sleep存在异常interruptedException
sleep时间达到后线程进入就绪状态
sleep(时间)指定当前线程阻塞的毫秒数(1000hs(毫秒)=1s(秒),一般一秒就够用
线程礼让(yield)
礼让线程,让当前允许的线程暂停,但不阻塞
让线程从运行的状态转换为就绪状态
让cpu重新调度,礼让不一定会成功,看cpu心情!
package com.wyh.thread; /** * @program: Thread * @description: 线程礼让 * @author: 魏一鹤 * @createDate: 2022-01-02 20:59 **/ //测试线程礼让 礼让不一定成功 只是让线程回到同一起跑线 public class TesThreadYield { public static void main(String[] args){ //创建线程执行体 ThreadYield threadYield=new ThreadYield(); new Thread(threadYield,"线程A").start(); new Thread(threadYield,"线程B").start(); } } class ThreadYield implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"开始执行"); //线程礼让 Thread.yield(); System.out.println(Thread.currentThread().getName()+"结束执行"); } }
线程强制执行(join)
- join合并线程,待此线程执行完成后,再开始执行其他线程,在此期间其他线程只能阻塞等待
- 可以把他想象成插队
- 需要被捕获异常InterruptedException
package com.wyh.thread; /** * @program: Thread * @description: 线程join强制插队 * @author: 魏一鹤 * @createDate: 2022-01-03 21:27 **/ //线程join测试 可以把它想象成插队 public class TestThreadJoin implements Runnable{ @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("vip来了"+i); } } public static void main(String[] args) throws InterruptedException { //启动线程 TestThreadJoin testThreadJoin = new TestThreadJoin(); Thread thread = new Thread(testThreadJoin); thread.start(); for (int i = 0; i < 500; i++) { //如果i==500 让run线程插队执行,main方法阻塞等待,等run方法执行完之后再执行 if(i==200){ thread.join(); } System.out.println("main启动线程"+i); } } }

