线程中断
需求:最近写swing界面,当界面切换的时候原先的线程马上停止并且新线程马上启动加载数据;由于界面数据是通过IO远程接受,并且数据量不小、这个时候点击切换到其他页面,这时数据还在通过IO在传送数据,这时候就需要马上终止线程;但在实际开发过程中只有stop方法能够实现其功能;其他的方法都只是将线程挂起,并没有将线程关闭。1.这时就是切换到其他页面,那么也是空页面,没有数据;2.假如线程关闭之后再切换页面,这个时候就会出现界面卡的情况。
网上线程中断的例子都不适用,由于我加载数据是通过流加载数据,这个时候网络连通性等都会成为影响因素,界面卡将是最大的bug。由于stop方法不安全,在大量测试之后,有时候它是关闭不了线程。线程关闭不了,新线程启动不了页面数据难以加载数据,就算新线程启动,但是页面还是加载不了数据、在开发工程中,理论上说不应该出现这种情况,走不同的通道,线程,数据流;那么他们之间不应该有这种情况,但是实际开发中就是这种情况。当线程stop关闭之后,功能一切正常。很奇怪……
网上提供的方法如下
那么如果需要停止一个线程时,应该怎么办?其实方法很简单,只是需要我们执行确定线程什么时候退出就可以了。仍用本例来说,只需要在ChangeObjectThread线程中增加一个stopMe()方法就可以了。
public static class ChangeObjectThread extends Thread {
// 用于停止线程
private boolean stopMe = true;
public void stopMe() {
stopMe = false;
}
@Override
public void run() {
while (stopMe) {
synchronized (ThreadStopSafeBoolean.class) {
int v = (int) (System.currentTimeMillis() / 1000);
user.setId(v);
// to do sth
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setName(String.valueOf(v));
}
// 让出CPU,给其他线程执行
Thread.yield();
}
}
}
在上面的代码里面,定义了一个标记变量stopMe,用于指示线程是否需要退出。当stopMe()方法被调用时,stopme就会被赋值为false,此时在代码里面的while(stopMe)就会检测到这个改动,线程就退出了。
可这不是问题出现的真正地方,而我的是流还没有结束,数据还没有接受完,就要退出线程,退出流,流在接受数据的时候是不关闭的,所有只有stop能够实现,然后切换到其他的界面;所有上述方法根本不能解决我的问题。
- 解决线程中断的方法如下:
public class MyThread implements Runnable{
private boolean running = false;
private boolean waiting = false;
private Thread thread;
private String name;
public MyThread(){
}
public MyThread(String name) {
this.name = name;
this.thread = new Thread(this);
}
//启动线程
public void start() {
running = true;
thread.start();
}
//挂起线程
public void suspend() {
if (waiting) {
return;
}
synchronized (this) {
this.waiting = true;
}
}
//恢复线程
public void resume() {
if (!waiting) {
return;
}
synchronized (this) {
this.waiting = false;
this.notifyAll();
}
}
//终止线程
public void stop() {
if (!running) {
return;
}
synchronized (this) {
running = false;
}
}
public void run() {
while (true) {
try {
// 线程挂起和退出处理
synchronized (this) {
if (!running) {
break;
}
if (waiting) {
this.wait();
}
}
// 应该做的事情
execute();
// 进入等待状态
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//真正要做的事情
private void execute() {
if(running && !waiting){
System.out.println(name + " is running...");
}
}
}
测试方法:
public static void main(String[] args) throws Exception {
MyThread a = new MyThread("Athread");
MyThread b = new MyThread("Bthread");
MyThread c = new MyThread("Cthread");
MyThread d = new MyThread("Dthread");
MyThread e = new MyThread("Ethread");
MyThread f = new MyThread("Fthread");
MyThread g = new MyThread("Gthread");
MyThread h = new MyThread("Hthread");
a.start();
b.start();
c.start();
d.start();
e.start();
f.start();
g.start();
h.start();
Thread.sleep(10000);
for(int i=0;i<10000;i++){
if(i==1000){
a.stop();b.stop();
c.stop();d.stop();
e.stop();f.stop();
g.stop();h.stop();
}
}
}