当前位置: 首页 > news >正文

三、线程状态

三、线程状态

3.1 线程停止

1.建议线程正常停止----->利用次数,不建议死循环

2.不要使用stop或者destroy等过时或者JDK不建议使用的方法

3.建议使用标志位----->设置标志位 (自己写stop方法)

public class TestStop implements Runnable{// 1.设置一个标志位private boolean flag = true;@Overridepublic void run() {int  i = 0;while (flag){System.out.println("run.......Thread"+i++);}}// 2.设置一个公开的方法停止线程,转换标志位public void stop(){this.flag = false;}public static void main(String[] args) {TestStop testStop = new TestStop();new Thread(testStop).start();for (int i = 0; i < 1000; i++) {System.out.println("main"+i);//当输出到main900的时候,线程testStop结束,run...Thread不在输出,只输出main901-main999if (i == 900){//调用stop方法切换标记位,让线程停止testStop.stop();System.out.println("该线程停止了");}}}
}

运行结果:

main0
run.......Thread0
main1
run.......Thread1
main2
run.......Thread2main和run...Thread交替出现
~~~~~~~main887
main888
run.......Thread906
main889
main890
main891
main892
main893
main894
main895
main896
main897
main898
main899
main900
run.......Thread907
run.......Thread908
该线程停止了
main901
main902
main903
main904
.........main990
main991
main992
main993
main994
main995
main996
main997
main998
main999

3.2 线程休眠-sleep

案例1:

//模拟网络延迟:方法问题的发生性
//如果不模拟延迟,线程不安全(后续学习会解决)火车票可能会被会被同一个人抢完
public class TestSleep implements Runnable{private int ticketNums = 10;@Overridepublic void run() {while (true){if (ticketNums <= 0){break;}//模拟延迟try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"---->拿了第"+ticketNums--+"张火车票");}}public static void main(String[] args) {TestSleep ticket = new TestSleep();new Thread(ticket,"小明").start();new Thread(ticket,"李华").start();new Thread(ticket,"黄牛").start();}
}

运行结果:

//火车票不被同一个人拿走,但线程不安全,出现一人或多人拿同一张票,后续在解决......
黄牛---->拿了第10张火车票
李华---->拿了第10张火车票
小明---->拿了第9张火车票
小明---->拿了第8张火车票
黄牛---->拿了第8张火车票
李华---->拿了第7张火车票
李华---->拿了第6张火车票
小明---->拿了第6张火车票
黄牛---->拿了第6张火车票
李华---->拿了第5张火车票
黄牛---->拿了第4张火车票
小明---->拿了第5张火车票
黄牛---->拿了第1张火车票
李华---->拿了第2张火车票
小明---->拿了第3张火车票原因------>线程不安全

案例2:

模拟倒计时,然后输出当前时间

//模拟倒计时
public class TestSleep02 {//模拟倒计时public static void tenDown() throws InterruptedException {int num = 10;while (true){Thread.sleep(1000);System.out.println(num--);if (num <= 0){break;}}}public static void main(String[] args) {try {tenDown();} catch (InterruptedException e) {e.printStackTrace();}//模拟打印当前时间Date startTime = new Date(System.currentTimeMillis());//获取当前系统时间while (true){try {Thread.sleep(1000);System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));startTime = new Date(System.currentTimeMillis());//更新当前时间} catch (InterruptedException e) {e.printStackTrace();}}}
}

运行结果:

10
9
8
7
6
5
4
3
2
1
15:36:23
15:36:24
15:36:25
15:36:26
15:36:27
15:36:28
......

3.3 线程礼让-yield

线程礼让:让当前正在执行的线程暂停,但不阻塞

将线程从运行状态转为就绪状态

让CPU重新调度,但不一定成功!

public class TestYield {public static void main(String[] args) {MyYield myYield = new MyYield();new Thread(myYield,"a").start();new Thread(myYield,"b").start();}}class MyYield implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"线程开始执行");Thread.yield();//礼让System.out.println(Thread.currentThread().getName()+"线程停止执行");}
}
//没有礼让--Yield
//按照顺序
a线程开始执行
a线程停止执行
b线程开始执行
b线程停止执行//礼让,输出a线程开始执行后,还没有输出停止,就礼让输出b线程开始执行
a线程开始执行
b线程开始执行
b线程停止执行
a线程停止执行

3.4 线程强制执行-Join

线程强制执行:原来主线程和子线程是并行的关系,使用Join后,就会变为串行的关系,也就是,子线程执行Join后,子线程插入到主线程中,必须要等子线程运行完才能运行主线程。

类比:好比几个人乱着,有个线程a使用Join()插到最前面,我执行完你们再抢。

//测试join方法  //理解为插队
public class TestJoin implements Runnable{@Overridepublic void run() {for (int i = 0; i < 50; i++) {System.out.println("线程vip来了"+i);}}public static void main(String[] args) throws InterruptedException {//启动我们的线程TestJoin testJoin = new TestJoin();Thread thread = new Thread(testJoin);thread.start();//主线程for (int i = 0; i < 50; i++) {if (i == 20){thread.join();//插队}System.out.println("main"+i);}}
}

运行结果:

//因为我这台电脑的处理器是四核的,所以刚开始输出会出现主线程和子线程都出现的情况(因为几个内核执行一个线程)
//当main中i==20,子线程使用Join()让塔先执行完,再执行main线程
main0
线程vip来了0
main1
线程vip来了1
main2
线程vip来了2
main3
线程vip来了3
main4
线程vip来了4
main5
线程vip来了5
main6
线程vip来了6
main7
线程vip来了7
main8
线程vip来了8
main9
线程vip来了9
main10
线程vip来了10
main11
线程vip来了11
main12
main13
线程vip来了12
main14
线程vip来了13
main15
线程vip来了14
main16
main17
main18
main19
线程vip来了15
线程vip来了16
线程vip来了17
线程vip来了18
线程vip来了19
线程vip来了20
线程vip来了21
线程vip来了22
线程vip来了23
线程vip来了24
线程vip来了25
线程vip来了26
线程vip来了27
线程vip来了28
线程vip来了29
线程vip来了30
线程vip来了31
线程vip来了32
线程vip来了33
线程vip来了34
线程vip来了35
线程vip来了36
线程vip来了37
线程vip来了38
线程vip来了39
线程vip来了40
线程vip来了41
线程vip来了42
线程vip来了43
线程vip来了44
线程vip来了45
线程vip来了46
线程vip来了47
线程vip来了48
线程vip来了49
main20
main21
main22
main23
main24
main25
main26
main27
main28
main29
main30
main31
main32
main33
main34
main35
main36
main37
main38
main39
main40
main41
main42
main43
main44
main45
main46
main47
main48
main49Process finished with exit code 0

3.5 线程状态观测

  • 线程状态。 线程可以处于以下状态之一:

    • NEW
      尚未启动的线程处于此状态。
    • RUNNABLE
      在Java虚拟机中执行的线程处于此状态。
    • BLOCKED
      被阻塞等待监视器锁定的线程处于此状态。
    • WAITING
      正在等待另一个线程执行特定动作的线程处于此状态。
    • TIMED_WAITING
      正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
    • TERMINATED
      已退出的线程处于此状态。

    一个线程可以在给定时间点处于一个状态。 这些状态是不反映任何操作系统线程状态的虚拟机状态。

    • [BLOCKED]   一个线程的线程状态阻塞等待监视器锁定。
      [NEW]    线程尚未启动的线程状态。
      [RUNNABLE]     可运行线程的线程状态。
      [TERMINATED]     终止线程的线程状态。
      [TIMED_WAITING]   具有指定等待时间的等待线程的线程状态。
      [WAITING]    等待线程的线程状态

案例:

//观察测试线程的状态
public class TestState {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{for (int i = 0; i < 5; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("/");});//观察状态Thread.State state = thread.getState();System.out.println(state);//NEW//观察启动后thread.start();//启动线程state = thread.getState();System.out.println(state);//Runwhile (state != Thread.State.TERMINATED){//只要线程不终止,就一直输出状态Thread.sleep(100);state = thread.getState();//更新状态System.out.println(state);//输出}//        thread.start();//出现错误,因为死亡后的线程不能再启动}
}
NEW
RUNNABLE
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
/
TERMINATEDProcess finished with exit code 0

3.6 线程优先级

  1. Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该先先调用那个线程来执行,优先级高的先调用的可能性高,但并不是一定是按照优先级来的。
  1. 线程的优先级用数字表示,范围从1~10

                Thread.MAX_PRIORITY = 10

                Thread.MIN_PRIORITY = 1

                Thread.NORM_PRIORITY = 5

  1. 使用一下方式修改或获取优先级

    getPriority() setPriority()

//测试线程的优先级
public class TestPrioruty extends Thread{public static void main(String[] args) {//输出主线程默认优先级System.out.println(Thread.currentThread().getName()+"------>"+Thread.currentThread().getPriority());MyPrioruty myPrioruty = new MyPrioruty();Thread t1 = new Thread(myPrioruty);Thread t2 = new Thread(myPrioruty);Thread t3 = new Thread(myPrioruty);Thread t4 = new Thread(myPrioruty);Thread t5 = new Thread(myPrioruty);Thread t6 = new Thread(myPrioruty);//先设置优先级,再启动t1.start();t2.setPriority(1);t2.start();t3.setPriority(4);t3.start();t4.setPriority(Thread.MAX_PRIORITY);t4.start();//        t5.setPriority(-1);
//        t5.start();
//
//        t6.setPriority(11);
//        t6.start();}}class MyPrioruty implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"------>"+Thread.currentThread().getPriority());}
}

3.7 守护(daemon)线程

线程分为用户线程守护线程

虚拟机必须确保用户线程执行完毕

虚拟机不用等待守护线程执行完毕

如:后台记录操作日志,监控内存,垃圾回收。

//测试守护线程
//上帝忽悠你
public class TestDaemon {public static void main(String[] args) {God god = new God();You you = new You();Thread thread = new Thread(god);thread.setDaemon(true);//默认是false表示是用户线程,正常的线程都是用户线程thread.start();//上帝守护线程启动new Thread(you).start();}
}//上帝
class God implements Runnable{@Overridepublic void run() {while (true){// 虚拟机不用等待守护线程执行完毕,所以守护线程最后死亡System.out.println("上帝忽悠你");}}
}class You implements Runnable{@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("你一生都痛苦的活着");}System.out.println("=============goodbye,world!=====================");}
}

运行结果:

你一生都痛苦的活着
你一生都痛苦的活着
你一生都痛苦的活着
你一生都痛苦的活着
你一生都痛苦的活着
=============goodbye,world!=====================
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你
上帝忽悠你

http://www.taodudu.cc/news/show-8457255.html

相关文章:

  • day22知识点总结:线程安全问题及解决方法 线程礼让
  • 线程休眠、中断、强制执行与礼让分析
  • 用java编写判断三角形_如何用java代码来做三角形的判断?
  • 线程的优先级、守护线程、礼让线程、插入线程、中断线程
  • Java多线程学习笔记(4)— “Thread类三个方法:线程休眠sleep()、线程礼让yield()、线程强制执行join()”
  • java多线程(三) —— Thread方法(休眠,礼让,强制执行,守护线程)
  • 多线程_10_礼让yield
  • yield() 初让线程(礼让线程)
  • 不礼让行人怎么抓拍的_权威发布:丹阳正式抓拍斑马线前不“礼让行人”,八张图告诉您如何正确礼让...
  • 苹果手机更改定位 - 爱思助手
  • 爱思助手“显示发送描述文件到设备失败”
  • 写一个python代码自动读取eⅹcle内容,把内容提交到网页
  • ACM MM 2023| CLE Diffusion:可控光照增强扩散模型(low light image enhancement)
  • App 的界面设计流程
  • Allegro16.6添加标注的方法
  • 老SDRAM和DDR SDRAM时序图与信号完整性仿真结合运用(2) -版本博客图片丢失,增加图片后又不能上传,shit.
  • 实战:内容营销如何吸引顾客 试试五个切入点
  • 关于外场测试的一点儿介绍
  • 笔记本用gpu运行tensorflow-gpu,keras写的老程序,结果与原来不一样,一脸懵逼。
  • 腾讯一面!说说ArrayList的遍历foreach与iterator时remove的区别,我一脸懵逼
  • 信心满满去面美团,结果被JVM9连问怼的一脸懵逼
  • 字节跳动面到这道题,有的读者一脸懵逼,有的读者笑嘻嘻
  • 初学网络安全一脸懵逼?看懂直接跪下!
  • 微信小程序app.json全局配置
  • 计算机毕业设计PHP+安卓美食菜谱App(源码+程序+lw+远程调试)
  • 同城厨师上门做饭系统源码做菜预约做饭家宴代厨轰趴app源码厨师入住+厨师傅端/前端语言uniapp
  • 历书中的哥伦布
  • GPS历书(Almanac)和星历(Ephemeris)有什么区别?
  • SSM之一点一滴:Object对象使用Field反射遍历书输出
  • how many days c语言,万年历书-C精粹的万年历C语言实例解析精粹这本书的万年历程序实在是看不懂, 爱问知识人...