多线程中有三种方式可以停止线程
-
使用stop方法强制使线程退出,但是该方法不太安全所以已经被废弃
-
设置标记位,可以使线程正常退出
-
使用Thread类中的一个interrupt()可以中断线程
-
第一种:stop方法
package com.li.线程中断和优先级0427;
public class TestMyTreadStop1 {
public static void main(String[] args){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(true){
i++;
System.out.println(Thread.currentThread().getName()+ " i=" + i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"thread-stop");
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.stop();
}
}
- 这种方法不安全,因为stop会解除由线程获取的所有锁定,当在一个线程对象上 调用stop()方法时,这个线程对象所运行的线程就会立即停止,假如一个线程正在执行synchronized void{x = 3;y = 4;}由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x=3;时,被调用了stop()方法,即使在同步块中,也会被stop,这样就产生了不完整数据。
-
第二种:标记位法
package com.li.线程中断和优先级0427;
public class TestMyThreadStop2{
public static void main(String[] args) throws InterruptedException {
MyTreadStop2 myThreadStop2 = new MyTreadStop2();
myThreadStop2.setName("Thread-Stop-2");
myThreadStop2.start();
Thread.sleep(5000);
myThreadStop2.setFlag(false);
}
}
class MyTreadStop2 extends Thread{
private boolean flag = true;
@Override
public void run() {
int i = 0;
while(flag){
i++;
System.out.println(Thread.currentThread().getName()+ " i=" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
-
第三种:使用Thread.interrupt()
package com.li.线程中断和优先级0427;
public class TestMyThreadStop3 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(true){
i++;
/**
*
* 判断是否有中断
*
* 这里阻塞之后线程调用了一个interrupt()方法
* 清除中断标志 就会抛出一个异常
* java.lang.InterruptedException
*/
boolean flag = Thread.currentThread().isInterrupted();
if (flag){
//此处处理线程业务退出的逻辑
break;
}
System.out.println(Thread.currentThread().getName()+ " i=" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
/**
* 这里退出阻塞状态 且中断标志自动清除
* 并且重新设置为false 所以此处bool为false
*/
boolean bool = Thread.currentThread().isInterrupted();
System.out.println(bool);
return;
}
}
}
},"thread-stop-1");
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
- interrupte()方法并不会立即执行中断操作;具体而言,这个方法只会给线程设置一个为true的中断标志(中断标志只是一个布尔类型的变量),而设置之后,则根据线程当前的状态进行不同的后续操作。如果,线程的当前态处于非阻塞状态,那么仅仅是线程的中断标志被修改为ue而已;如果线程的当前状态处于阻塞状态,那么在将中断标志设置为tue后,还会有如下三种情况之一的操作:
- 如果是wat.seep以jon三个方法引起的阻塞,那么会将线程的中断标志重新设置为 false,并抛出InterruptedException
- 如果在中断时,线程正处于非阻塞状态,则将中断标志修改为rue而在此基础上,一旦进入阻塞状态,则按照阻塞状态的情况来进行处理;例如,一个线程在运行状态中,其中断标志被设置为true之后,一旦线程调用了wait,join,sleep方法中的一种,立马抛出个InterruptedException,且中断标志被程序会自动清除,重新设置为false