Java多线程编程核心技术(第3版)
上QQ阅读APP看书,第一时间看更新

1.11.9 使用return;语句停止线程的缺点及相应的解决方案

将interrupt()方法与return;语句结合使用也能实现停止线程的效果。

创建测试项目useReturnInterrupt,线程类MyThread.java代码如下:


package extthread;

public class MyThread extends Thread {

@Override
public void run() {
    while (true) {
        if (this.isInterrupted()) {
            System.out.println("停止了!");
            return;
        }
        System.out.println("timer=" + System.currentTimeMillis());
    }
}

}

运行类Run.java代码如下:


package test.run;

import extthread.MyThread;

public class Run {

public static void main(String[] args) throws InterruptedException {
    MyThread t=new MyThread();
    t.start();
    Thread.sleep(2000);
    t.interrupt();
}

}

程序运行结果如图1-53所示。

图1-53 线程成功停止

相比“抛异常”法,虽然使用“return;”在代码结构上可以更加方便地停止线程,不过还是建议使用“抛异常”法,因为该方法可以在catch块中对异常的信息进行统一处理。下面用具体示例来说明。使用“return;”来设计代码:


public class MyThread extends Thread {
    @Override
    public void run() {
        // insert操作
        if (this.interrupted()) {
            System.out.println("写入log info");
            return;
        }
        // update操作
        if (this.interrupted()) {
            System.out.println("写入log info");
            return;
        }
        // delete操作
        if (this.interrupted()) {
            System.out.println("写入log info");
            return;
        }
        // select操作
        if (this.interrupted()) {
            System.out.println("写入log info");
            return;
        }
        System.out.println("for for for for for");
    }
}

在每个“return;”代码前都要搭配一个写入日志的代码,这样会使代码出现冗余,并没有集中处理日志,不利于代码的阅读与扩展,这时可以使用“抛异常”法来简化这段代码:


public class MyThread2 extends Thread {
    @Override
    public void run() {
        try {
            // insert操作
            if (this.interrupted()) {
                throw new InterruptedException();
            }
            // update操作
            if (this.interrupted()) {
                throw new InterruptedException();
            }
            // delete操作
            if (this.interrupted()) {
                throw new InterruptedException();
            }
            // select操作
            if (this.interrupted()) {
                throw new InterruptedException();
            }
            System.out.println("for for for for for");
        } catch (InterruptedException e) {
            System.out.println("写入log info");
            e.printStackTrace();
        }
    }
}

写入日志的功能在catch块被集中统一处理了,代码风格更加规范。