首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是方法名称或机制来覆盖“当线程被释放”行为。

什么是方法名称或机制来覆盖“当线程被释放”行为。
EN

Stack Overflow用户
提问于 2018-05-17 11:54:07
回答 3查看 89关注 0票数 2

我想重写行为,以便ExecutorService调用自定义方法。当线程被释放时,我想清除所有ThreadLocal变量。不太熟悉api,或者可能已经存在一些东西。

不确定线程池在线程完成工作时是如何管理线程的,但我假设线程池不会销毁线程,因为如果线程池不销毁线程,那么根据ThreadLocal描述,这将是非常昂贵的:

代码语言:javascript
复制
Each thread holds an implicit reference to its copy of a thread-local
 * variable as long as the thread is alive and the {@code ThreadLocal}
 * instance is accessible; after a thread goes away, all of its copies of
 * thread-local instances are subject to garbage collection (unless other
 * references to these copies exist).

我需要清除ThreadLocal

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-05-17 12:16:20

对于一个ExecutorService,你可以做一个自我清洁的任务。

代码语言:javascript
复制
public CleanerTask implements Runnable {
    private Disposable realRunnable;

    public CleanerTask(Disposable d) {
        realRunnable = d;
    }

    public void run() {
        realRunnable.run();
        realRunnable.dispose();
    }
}

在本例中,Disposable是一个扩展Runnable的接口,并提供了一个清除ThreadLocal变量的dispose()方法。实现保证run()dispose()在同一个线程中运行,因此可以安全地清除变量。

然后,在将任务提交给执行者之前,只需确保将任务包装在CleanerTask中即可。

但是,,如果您没有绑定到ExecutorService,您可以扩展ThreadPoolExecutor,它提供了一个afterExecute方法。然后您只需在那里调用dispose() (在检查Runnable的类型是否正确之后)。

(我最初以为afterExecute没有在运行任务的线程中运行,但幸运的是,我想错了。)

票数 2
EN

Stack Overflow用户

发布于 2018-05-17 12:27:13

不确定您是否以正确的方式考虑线程和线程池。线程是用start()启动的,当它们的执行完成后,它们就被销毁了。线程的创建方式和时间取决于您的executor服务实现.您可能有一个只有在当前线程中运行任务。的执行器服务。池执行器服务可能使用无限循环启动其线程,等待提交的任务.然而,即使线程池通常也是灵活的,因为池只保留了有限数量的等待线程,如果有更多的线程,它就会让它们死掉(打破无限睡眠循环)。通常,如果执行抛出异常,线程也会被丢弃。

让线程-局部变量在一次执行中存活并不是一种好做法。每次执行之后,你都应该清理你的线程--本地人。不要等待线程的处理/销毁。

TL;博士并不试图黑入“线程破坏”,而是使用try/finally开始每一次执行,以设置和清理线程局部变量。

票数 0
EN

Stack Overflow用户

发布于 2018-05-17 14:07:02

线程将被实现线程池的executorservice重用,除非删除,否则这些线程本地条目将保留在线程跨任务的位置。如果您知道当一个任务完成时,它的线程本地值现在是不相关的,那么您可以清除它的就像Kayaman说的

但是,线程局部变量的要点是,它们可以跨不同的组件使用,用于不同组件无法管理其作用域的情况。例如,web应用程序可以在带HTTP请求的过程中在过滤器中的线程本地中放置一些东西,使web控制器和服务可以在请求过程中使用,并在返回时清理过滤器中的线程本地。因此,在本例中,线程本地值的范围由过滤器管理,以便对参与该线程请求的所有对象可用,其中在“正常”(意味着不像Play这样的异步非阻塞设置) web应用程序中,请求由应用服务器中的一个线程处理。

如果确定不再需要ThreadLocal值的作用域对您来说如此简单,任务就可以清理它,那么您的代码听起来就像在不必要地使用ThreadLocals。我建议删除这些ThreadLocals并在任务中使用局部变量。不应将ThreadLocal用作参数传递的简单替代方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50390814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档