线程是一个动态执行的过程,它也有一个从产生到死亡的过程
1.线程终止状态
- 使用退出标志,使线程正常退出,也就是当 run() 方法完成后线程中止。
- 使用 stop() 方法强行终止线程,但是不推荐使用这个方法,该方法已被弃用。
- 使用 interrupt 方法中断线程。
使用标记终止线程:
public class ServerThread extends Thread {
//volatile修饰符用来保证其它线程读取的总是该变量的最新的值
public volatile boolean flag = false;
@Override
public void run() {
ServerSocket serverSocket = new ServerSocket(8080);
while(!flag){
serverSocket.accept(); //阻塞等待客户端消息
...
}
}
public static void main(String[] args) {
ServerThread t = new ServerThread();
t.start();
...
t.flag = true; //修改标志位,退出线程
}
}
使用 interrupt() 中断线程:
现在我们知道了使用 stop() 方式停止线程是非常不安全的方式,那么我们应该使用什么方法来停止线程呢?答案就是使用 interrupt() 方法来中断线程。
需要明确的一点的是:interrupt() 方法并不像在 for 循环语句中使用 break 语句那样干脆,马上就停止循环。调用 interrupt() 方法仅仅是在当前线程中打一个停止的标记,并不是真的停止线程。
也就是说,线程中断并不会立即终止线程,而是通知目标线程,有人希望你终止。至于目标线程收到通知后会如何处理,则完全由目标线程自行决定。这一点很重要,如果中断后,线程立即无条件退出,那么我们又会遇到 stop() 方法的老问题。
事实上,如果一个线程不能被 interrupt,那么 stop 方法也不会起作用。
public class Main extends Thread{
@Override
public void run() {
super.run();
for(int i = 0; i <= 1000; i++) {
if(Thread.currentThread().isInterrupted()) {
break;
}else {
System.out.println("i=" + i);
}
}
}
public static void main(String[] args) throws Exception {
Main main=new Main();
main.start();
Thread.sleep(1); //暂停sleep 模拟网络延迟
main.interrupt();
}