如何在退出线程时执行代码

3

我希望在线程结束之前执行一些代码。因此,我正在寻找一种类似于dispose(),tearDown()的方法来确保在线程退出之前执行特定任务。


很难确定如何在不了解线程信息的情况下更改线程。例如,它是否是守护线程?任务是什么样子的?任务是否在无限循环中执行?目前你如何处理线程中断? - Pshemo
它是一个在线程池执行器中实现为Runnable的任务。 - tip
3个回答

3

您可以将要执行的代码包装在一个单独的线程中,该线程在您自己的具有try/finally块的代码中,并从try中调用“真正”的Runnablerun方法,如下所示:

final Runnable realRunnable = ... // This is the actual logic of your thread
(new Thread(new Runnable() {
    public void run() {
        try {
            realRunnable.run();
        } finally {
            runCleanupCode();
        }
    }
})).start();
< p> runCleanupCode() 的代码将在运行实际线程逻辑的同一线程中执行。

是的,也就是说“如果你想让某个函数中的代码最后执行,就把它放在最后面” :) - Martin James

3

其他答案没有考虑到你正在谈论线程池。以下是你需要做的:

private static class MyThreadFactory implements ThreadFactory {
    public Thread newThread(final Runnable r) {
        return new Thread() {
            public void run() {
                try {
                    r.run();
                } finally {
                    // teardown code
                }
            }
        };
    }

}
public static void main(String[] args) {
    ThreadPoolExecutor exec = new ThreadPoolExecutor(10, 20, 100, TimeUnit.SECONDS, null, new MyThreadFactory());
}

2
将dasblinkenlight的回答再深入一些(可能有点过头了?):
class ThreadWithCleanup extends Thread {
    final Runnable main;
    final Runnable cleanup;

    ThreadWithCleanup(Runnable main, Runnable cleanup) {
        this.main = main;
        this.cleanup = cleanup;
    }

    @Override
    public void run() {
        try {
            main.run();
        } finally {
            cleanup.run();
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        Runnable m = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello from main.");
                throw new RuntimeException("Bleah!");
            }
        };
        Runnable c = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello from cleanup.");
            }
        };
        ThreadWithCleanup threadWithCleanup = new ThreadWithCleanup(m, c);
        threadWithCleanup.start();
        try {
            threadWithCleanup.join();
        } catch (InterruptedException ex) {
        }
    }
}

我以前曾认为我永远不会看到一个合法的理由来扩展Thread类!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接