线程基础-结束线程
1.stop()方法
- 略
2.使用共享变量
java
package com.ysf.day0427;
public class Tst03ShareVar {
static volatile boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
while (flag){
//处理业务
}
System.out.println("任务结束");
},"share-1");
t.start();
Thread.sleep(1000L);
flag = false;
}
}
3.使用interrupt
3.1 interrupt标记位
- 线程中存在一个标记位interrupt,来标识线程是否被打断
- 该标记位默认情况下是false
3.2 查询线程标记位
- 对象方法:isInterrupted()
java
package com.ysf.day0427;
public class Tst04QueryInterrupt {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
for (int i = 0;i<5;i++){
System.out.println(i);
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"interrupt-1");
t1.start();
Thread.sleep(1000L);
System.out.println(t1.isInterrupted());
}
}
3.3设置线程interrupt标记位为true
- 对象方法:interrupt()
- 作用:
- 改变标记位为true
- 打断线程的WAITING或者TIMED_WAITING状态
- 用法:
- 当用作设置线程结束的方法时(没有sleep,没有wait),标记位会有明显改变
- 当作为打断线程WAITING或者TIMED_WAITING状态的方法时,线程的标记位是不会被改变的
java
package com.ysf.day0427;
import java.util.Date;
public class Tst05SetInterrupt {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
int count = 0;
while (!Thread.currentThread().isInterrupted()){
System.out.println("业务处理" + count);
count++;
// 这里用于证明,在调用了interrupt()方法后,并没有改变线程的标记位
System.out.println(Thread.currentThread().isInterrupted());
try {
System.out.println("开始睡眠");
// 睡眠50秒,方便被main线程打断,可以清晰的看出线程并没有睡足50秒
Thread.sleep(50000L);
} catch (InterruptedException e) {
// 当捕获到这个异常的时候会有两种情况
// 情况1:我只想打断沉睡
// 情况2:我想退出线程
if (count<20){
// 模拟情况1,如果count小于20的话,那我只想打断沉睡
continue;
}else {
// 模拟情况2,如果count不小于20的话,那我想退出线程
// 这里我们不用break或return,我们使用改变标记位的方式
// 为什么这里还要再打断一次,因为main线程的打断只是改变了线程WAITING状态,并没有改变标记位
Thread.currentThread().interrupt();
}
}
}
System.out.println("线程结束");
},"interrupt-1");
t1.start();
// 睡一秒,等待t线程启动
Thread.sleep(1000L);
for (int i = 0;i<21;i++){
Thread.sleep(1000L);
t1.interrupt();
}
}
}
3.3查询线程标记位,并将标记位设置为false
- 静态方法:Thread.interrupted()
- 作用:
查询线程的标记位,并且将标记位设置为false
java
package com.ysf.day0427;
public class Tst06SetInterruptFalse {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
int count = 0;
String name = Thread.currentThread().getName();
while (!Thread.currentThread().isInterrupted()){
System.out.println(name + "==>" + count);
count++;
// 这里用于证明,在调用了interrupt()方法后,并没有改变线程的标记位
System.out.println(Thread.currentThread().isInterrupted());
try {
System.out.println(name + "==>" + "开始睡眠");
// 睡眠50秒,方便被main线程打断
Thread.sleep(50000L);
} catch (InterruptedException e) {
// 当捕获到这个异常的时候会有两种情况
// 情况1:我只想打断沉睡
// 情况2:我想退出线程
if (count<3){
// 模拟情况1,如果count小于3的话,那我只想打断沉睡
continue;
}else {
// 模拟情况2,如果count不小于3的话,那我想退出线程
// 这里我们不用break或return,我们使用改变标记位的方式
// 为什么这里还要再打断一次,因为main线程的打断只是改变了线程WAITING状态,并没有改变标记位
System.out.println(name + "==>" + "count不小于3了");
Thread.currentThread().interrupt();
// 那如果我在调用了打断之后,我又有其他情况不想退出了呢?
// 我们可以在此基础上再调用一次静态方法
System.out.println(name + "==>" + Thread.interrupted());
}
}
}
System.out.println(name + "==>" + "线程结束");
},"interrupt-1");
t1.start();
// 睡一秒,等待t线程启动
Thread.sleep(1000L);
for (int i = 0;i<3;i++){
String name = Thread.currentThread().getName();
Thread.sleep(1000L);
System.out.println(name + "==>" + "开始执行第" + i + "次打断");
t1.interrupt();
}
}
}