Thread实现多线程三

接上文,关系到线程运行状态的几个方法:

6)interrupt方法

interrupt,顾名思义,即中断的意思。单独调用interrupt方法可以使得处于阻塞状态的线程抛出一个异常,也就说,它可以用来中断一个正处于阻塞状态的线程;另外,通过interrupt方法和isInterrupted()方法来停止正在运行的线程。

下面看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.IOException;

public class ThreadInterupt {
public static void main(String[] args) throws IOException {
ThreadInterupt test = new ThreadInterupt();
MyThread thread = test.new MyThread();
//线程开始
System.out.println("进入线程" + Thread.currentThread().getName());
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {

}
thread.interrupt();
}

class MyThread extends Thread{
@Override
public void run() {
try {
System.out.println("线程" + Thread.currentThread().getName() + "进入睡眠状态");
Thread.currentThread().sleep(10000);
System.out.println("线程" + Thread.currentThread().getName() + "睡眠完毕");
} catch (InterruptedException e) {
System.out.println("线程" + Thread.currentThread().getName() + "得到中断异常");
}
System.out.println("线程" + Thread.currentThread().getName() + "run方法执行完毕");
}
}
}

执行结果 :

1
2
3
4
进入线程main
线程Thread-0进入睡眠状态
线程Thread-0得到中断异常
线程Thread-0run方法执行完毕

从这里可以看出,在主线程中,通过interrupt方法可以中断处于阻塞状态的线程。

那么能不能中断处于非阻塞状态的线程呢?看下面这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.io.IOException;

public class InteruptRunningThread {

public static void main(String[] args) throws IOException {
InteruptRunningThread test = new InteruptRunningThread();
//线程开始
System.out.println("进入线程" + Thread.currentThread().getName());

MyThread thread = test.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {

}
thread.interrupt();
}

class MyThread extends Thread{
@Override
public void run() {
int i = 0;
while(i < Integer.MAX_VALUE){
System.out.println("while循环, i = " + i + "\r\n");
i++;
}
}
}
}

执行结果:

1
2
3
4
5
6
while循环, i = 394572

while循环, i = 394573

while循环, i = 394574
...//还在继续

运行该程序会发现,while循环会一直运行直到变量i的值超出Integer.MAX_VALUE。所以说直接调用interrupt方法不能中断正在运行中的线程。

但是如果配合isInterrupted()能够中断正在运行的线程,因为调用interrupt方法相当于
将中断标志位置为true,那么可以通过调用isInterrupted()判断中断标志是否被置位来中断线程的执行。比如下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.IOException;

public class InteruptRunningThread {

public static void main(String[] args) throws IOException {
InteruptRunningThread test = new InteruptRunningThread();
//线程开始
System.out.println("进入线程" + Thread.currentThread().getName());

MyThread thread = test.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {

}
thread.interrupt();
System.out.println("结束线程" + Thread.currentThread().getName());
}

class MyThread extends Thread{
@Override
public void run() {
int i = 0;
/*while(i < Integer.MAX_VALUE){
System.out.println("while循环, i = " + i + "\r\n");
i++;
}*/
while(!isInterrupted() && i<Integer.MAX_VALUE){
System.out.println(i+" while循环");
i++;
}
}
}
}

执行结果:

1
2
3
4
138537 while循环
138538 while循环
138539 while循环
结束线程main

但是一般情况下不建议通过这种方式来中断线程,一般会在MyThread类中增加一个属性 isStop来标志是否结束while循环,然后再在while循环中判断isStop的值。
那么就可以在外面通过调用setStop方法来终止while循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyThread extends Thread{
private volatile boolean isStop = false;

@Override
public void run() {
int i = 0;
while(!isStop && i < Integer.MAX_VALUE){
System.out.println("while循环, i = " + i + "\r\n");
i++;
}
}

public void setStop(boolean stop){
this.isStop = stop;
}
}

7)stop方法

stop方法已经是一个废弃的方法,它是一个不安全的方法。因为调用stop方法会直接终止run方法的调用,并且会抛出一个ThreadDeath错误,如果线程持有某个对象锁的话,会完全释放锁,导致对象状态不一致。所以stop方法基本是不会被用到的。

8)destroy方法

destroy方法也是废弃的方法。基本不会被使用到。