如何停止java的线程一直是一个开发多线程程序常遇到的一个问题。也有好多同学问过,所以今天在这里总结一下希望可以让更多的人知道在java中如何安全的结束一个正在运行的线程。
在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(), stop(),
stop(Throwable) and suspend(), destroy() and
resume()。通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留。
那么,我们究竟应该如何停止线程呢?这里我们介绍两种方法:
1.使用共享变量的方式
在这种方式中,之所以引入共享变量,是因为该变量可以被多个执行相同任务的线程用来作为是否中断的信号,通知中断线程的执行。
public class ThreadFlag extends Thread
{
public volatile boolean exit = false;
public void run()
{
while (!exit);
}
public static void main(String[] args) throws Exception
{
ThreadFlag thread = new ThreadFlag();
thread.start();
sleep(3000); // 主线程延迟3秒
thread.exit = true; // 终止线程thread
thread.join();
System.out.println("线程退出!");
}
}
在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false。在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值。
建议使用如下的方法来停止线程:
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
2. 使用interrupt方法终止线程
如果一个线程由于等待某些事件的发生而被阻塞,又该怎样停止该线程呢?
这种情况经常会发生,比如当一个线程由于需要等候键盘输入而被阻塞,或者调用Thread.join()方法,或者Thread.sleep()方法,在网络中调用ServerSocket.accept()方法,或者调用了DatagramSocket.receive()方法时,都有可能导致线程阻塞,使线程处于处于不可运行状态时,即使主程序中将该线程的共享变量设置为true,但该线程此时根本无法检查循环标志,当然也就无法立即中断。
这里我们给出的建议是,不要使用stop()方法,而是使用Thread提供的interrupt()方法,因为该方法虽然不会中断一个正在运行的线程,但是它可以使一个被阻塞的线程抛出一个中断异常,从而使线程提前结束阻塞状态,退出堵塞代码。
class MyThread extends Thread {
volatile boolean stop = false;
public void run() {
while (!stop) {
System.out.println(getName() " is running");
try {
sleep(1000);
}catch (InterruptedException e) {
System.out.println("week up from blcok...");
stop = true; // 在异常处理代码中修改共享变量的状态
}
}
System.out.println(getName() " is exiting...");
}
}
class InterruptThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
MyThread m1 = new MyThread();
System.out.println("Starting thread...");
m1.start();
Thread.sleep(3000);
System.out.println("Interrupt thread...: " m1.getName());
m1.stop = true; // 设置共享变量为true
m1.interrupt(); // 阻塞时退出阻塞状态
Thread.sleep(3000); // 主线程休眠3秒以便观察线程m1的中断情况
System.out.println("Stopping application...");
}
}
注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。
尚学堂Java培训开课时间表
西安校区
Java全程就业培训【脱产班】
开课时间:2017年04月25日 抢座中..
Android全程就业培训【脱产班】
开课时间:已开班 少量余座抢座中..
Web前端全程就业培训【脱产班】
开课时间:已开班 少量余座 抢座中..
电话:029-62258374 029-62326079
地址:陕西省西安市高新区科技二路西安软件园天泽大厦五楼
郑州校区
Java培训【脱产班】
开课时间:已开班 少量余座 抢座中..
电话:0371-58500958
地址:河南省郑州市金水区东风路与文化路交叉南100米
什么是脱产班:
脱产班就是参加工作后再去校内进行学习
一种学习方式。其管理模式与高校普通班
级一样,学习期间完全脱离生产不在原单
位工作,全身心的进行全日制学习。不占
用学生周六和周日的工作时间,对学生有
正常的、相对固定的授课教室和管理要求
,有稳定的寒暑假安排。
一个有用的公众号
尚学堂java培训
Android
web前端
培训基地 亲爱的同学们:
尚学堂java培训开班前有免费试听课程,想学习又不太确定的同学们赶紧联系老师,获取免费试听名额(每个班级的名额是有限的哦,速联速得)。
获取方式:打开【尚学堂java培训】公众号,点击-精品课程-我要试听-联系老师获取免费试听名额;或直接联系公众号,让“万能”的小编为您解决一切问题!
|