线程休眠:sleep()
注意点:
- sleep(时间)指定当前线程阻塞的毫秒数
- sleep存在异常InterruptedException
- sleep时间达到后线程进入就绪状态
- sleep可以模拟网络延时,倒计时等
- 每一个对象都有一个锁,sleep不会释放锁;
示例一:我们拿售票的例子演示模拟网络延迟
上代码
package com.kuang.thread;
/**
* @ClassName TestSleep1
* @Description 线程休眠 模拟网络延迟
* @Author 麻虾
* @Date 2021/4/27 20:27 27
* @Version 1.0
*/
//每个对象都有一把锁,sleep不会释放锁
//sleep模拟网络延迟
//最大的作用:放大问题的发生性。 比如这个,没有延迟,看不出错误,有了延迟就看出来了问题
public class TestSleep1 implements Runnable {
//票数
private int ticketNums = 10;
@Override
public void run() {
//线程体
//买票 只要还有票,就一直拿
while (true) {
//判断什么时候结束
if (ticketNums <= 0) {
break;
}
System.out.println(Thread.currentThread().getName() + "---->抢到了第" + ticketNums-- + "张票");
}
}
public static void main(String[] args) {
TestSleep1 testTicket = new TestSleep1();
new Thread(testTicket,"学生 ").start();
new Thread(testTicket,"老师").start();
new Thread(testTicket,"校长").start();
}
}
以上代码是没有模拟延迟的,我们先看一下没有模拟延迟的结果如何:
校长---->抢到了第9张票
学生 ---->抢到了第8张票
学生 ---->抢到了第6张票
学生 ---->抢到了第5张票
学生 ---->抢到了第4张票
学生 ---->抢到了第3张票
学生 ---->抢到了第2张票
学生 ---->抢到了第1张票
老师---->抢到了第10张票
校长---->抢到了第7张票
发现:结果貌似没有什么问题。
我们把在run()里面加入以下模拟延迟的代码:
//模拟延迟:sleep(毫秒),sleep需要捕获异常
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
再来看一下结果:
学生 ---->抢到了第8张票
校长---->抢到了第9张票
老师---->抢到了第10张票
老师---->抢到了第7张票
学生 ---->抢到了第5张票
校长---->抢到了第6张票
学生 ---->抢到了第4张票
老师---->抢到了第3张票
校长---->抢到了第2张票
校长---->抢到了第1张票
老师---->抢到了第1张票
学生 ---->抢到了第1张票
发现:出现了数据紊乱,学生,校长,老师都拿到了第1张票,线程是不安全的
这就体现了sleep() 最大的作用:放大问题的发生性。 比如这个,没有延迟,看不出错误,有了延迟就看出来了问题
示例二:利用sleep实现倒计时/获取系统时间
1.打印系统当前时间 (每隔一秒打印一次时间)
package com.kuang.thread;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @ClassName TestSleep2
* @Description 线程休眠
* @Author 麻虾
* @Date 2021/4/27 20:52 52
* @Version 1.0
*/
public static void main(String[] args) {
//打印当前系统时间 常用类Data,在java.util
//获取系统当前时间System.currentTimeMillis()
Date startTime = new Date(System.currentTimeMillis());
while (true){
//每隔一秒打印一次时间
try {
Thread.sleep(1000);
//打印时间
//时间格式化工厂SimpleDateFormat("HH:mm:ss")
System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
//更新当前时间
startTime = new Date(System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果如下:不停地(每隔一秒)打印系统当前时间
00:37:20
00:37:21
00:37:22
00:37:23
00:37:24
00:37:25
00:37:26
00:37:27
00:37:28
00:37:29
00:37:30
00:37:31
00:37:32
00:37:33
00:37:34
00:37:35
2.倒计时
package com.kuang.thread;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @ClassName TestSleep2
* @Description 线程休眠 模拟倒计时
* @Author 麻虾
* @Date 2021/4/27 20:52 52
* @Version 1.0
*/
//模拟倒计时
public class TestSleep2 {
public static void tenDown() throws InterruptedException{
int num = 10;
//每一秒钟走一下,走十秒钟
while (true){
//一定别忘了sleep需要捕获异常,也可以在方法出抛出throws异常
Thread.sleep(1000);
System.out.println(num--);
if (num <= 0){
break;
}
}
}
public static void main(String[] args) {
//1.倒计时
//定义方法时抛出了异常,所以调用的时候也必须捕获异常,否则报错
try {
tenDown();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
结果如下:
10
9
8
7
6
5
4
3
2
1
Process finished with exit code 0