Day27-线程停止、线程休眠、线程礼让、Join
线程停止
线程状态
线程方法
停止线程
- 不推荐适应JDK文档中的stop()、destory()方法。
- 推荐线程自己停止下来
- 建议使用一个标志位进行终止变量当flag=false,则终止线程运行。
package com.ghy.state;
//测试stop
//1.建议线程正常停止》利用次数,不建议死循环
//2.建议使用标志位》设置一个标志位
//3.不要使用过时的方法和jdk不推荐的方法
public class TestStop implements Runnable{
//设置一个标志位
private boolean flag = true;
@Override
public void run() {
int i= 0;
while(flag){
System.out.println("小赵正在睡觉......"+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 <=100; i++) {
System.out.println("小龚正在睡觉......"+i);
if(i==90){
//调用stop方法(自己写的),切换标志位让线程停止
testStop.stop();
System.out.println("小赵起床啦!");
}
}
}
}
当主线程的i跑到90时(小龚正在睡觉…90),线程停止(小赵起床啦!),然后主线程一直跑到结束(小龚正在睡觉…100)。
输出
线程休眠
1000毫秒=1秒
- 模拟倒计时
package com.ghy.state;
//模拟网络延时,放大问题的发生性。
//模拟倒计时
public class TeasSleep {
public static void main(String[] args) {
try {
tenDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void tenDown() throws InterruptedException {
int num=10;
while(true){
Thread.sleep(1000);//每一秒钟,跑一下
System.out.println(num--);
if(num<=0){
System.out.println("小赵出现啦!");
break;
}
}
}
}
输出
10
9
8
7
6
5
4
3
2
1
小赵出现啦!
- 每秒钟输出系统当前时间
package com.ghy.state;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
import org.w3c.dom.ls.LSOutput;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestSleep2 {
public static void main(String[] args) {
//打印当前系统时间
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();
}
}
}
//时间每秒输出一下
public static void Down() throws InterruptedException {
int num=10;
while(true){
Thread.sleep(1000);
System.out.println(num--);
if(num<=0){
break;
}
}
}
}
输出
22:33:45
22:33:46
22:33:47
22:33:48
22:33:49
22:33:50
22:33:51
......
线程礼让
package com.ghy.state;
//测试礼让线程
//礼让不一定成功,看CPU心情
public class TestYield {
public static void main(String[] args) {
MyYield myYield =new MyYield();
//启动线程
new Thread(myYield,"弗洛伊德").start();
new Thread(myYield,"阿德勒").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"叫小赵开始学习!");
Thread.yield();//线程礼让
System.out.println(Thread.currentThread().getName()+"叫小赵停止学习!");
}
}
输出
- 礼让成功(弗洛伊德线程执行礼让,让弗洛伊德和阿德勒在同一起跑线上,让CPU重新选择,礼让成功就是CPU选择了另外一个线程)
弗洛伊德叫小赵开始学习!
阿德勒叫小赵开始学习!
阿德勒叫小赵停止学习!
弗洛伊德叫小赵停止学习!
- 礼让失败
弗洛伊德叫小赵开始学习!
弗洛伊德叫小赵停止学习!
阿德勒叫小赵开始学习!
阿德勒叫小赵停止学习
Join
- Join合并线程,待此线程执行完成后,在执行其他线程,其他线程阻塞
- 可以想象成插队
package com.ghy.state;
//测试Join
//可以想象为插队
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("大小姐小赵插队,统统闪开!"+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 < 100; i++) {
if(i==80){
thread.join();//插队,需要抛出异常。主线程被人插队,当主线程到80时,其他都等待,让插队的先执行。
}
System.out.println("小龚子老老实实排队。"+i);
}
}
}
输出
当主线程执行到80时执行插队,直到VIP线程运行完。(之前是并发执行,到后面join就只执行VIP小赵线程,直到结束再执行其他线程)