我正在开发一个多线程应用程序,它可以从多个来源读取数据,执行一些计算,并将结果写入多个输出。我确实有几个读取器线程,几个计算线程和几个写入器。每种类型的线程数量在配置中给出。我希望将这些线程命名为:"reader-1“、"reader-2”、"writer-1“等。
因此,我想使用org.apache.commons.lang3.concurrent.BasicThreadFactory来实现这个目的。我确实写了以下代码:
BasicThreadFactory threadFactory = new BasicThreadFactory.Builder()
.namingPattern("%s-%d")
.daemon(false)
.priority(Thread.MAX_PRIORITY)
.build();
ExecutorService executors = Executors.newFixedThreadPool(config.getPoolSize(), threadFactory);然而,我找不到任何地方,我如何在提交时指定工作线程的名称和编号。我搜索了数百个链接,没有看到一个我该怎么做的例子。我正在创建我的Callable
Callable reader = new BatchFileReader(config);
for(int i = 1; i <= maxReaders; i++) {
executors.submit(reader);
}除了Runnable/Callable实例之外,Submit方法没有任何其他参数。我不知道在哪里可以给线程工厂指定字符串“thread”和它的序列号。如果有人能给我一个提示,我将不胜感激。
发布于 2020-12-31 21:19:23
如果您真的想设置执行提交的Callable/Runnable的Thread的名称,只需将名称提供给Callable/Runnable,并让它设置运行它的Thread的名称,只需调用Thread.currentThread().setName(...)即可:
public class BatchFileReader implements Runnable {
private final String name;
public BatchFileReader(final String name /*, other arguments go here...*/) {
this.name = Objects.requireNonNull(name);
}
@Override
public void run() {
Thread.currentThread().setName(name);
//Do your work here...
}
}我期望它能独立于任何Executor实现工作,假设每个Thread一次只能运行一个给定的任务,据我所知确实是这样。如果一个Thread可以以(伪)并行的方式同时运行多个Callable/Runnable,那么这种方法将不起作用。
我还研究了对每个提供的Executor实现进行子类化,但这会更麻烦一些。至少在ThreadPoolExecutor上,您可以通过将其子类化并覆盖ThreadPoolExecutor#beforeExecute和两个AbstractExecutorService#newTaskFor方法来实现这一点,如果您正在使用任何submit方法来提交Callables/Runnables。如果您只是将execute用于Runnable,那么您将只需要覆盖ThreadPoolExecutor#beforeExecute。但话又说回来,您必须在其中保留对Runnable名称的引用(以便可以将其传递给ThreadPoolExecutor#beforeExecute中的Thread )。
我注意到的另一件事是关于你是否真的必须依赖Thread的名字的问题……我的意思是,如果你只是在你提供的Callable/Runnable方法中与他们的call/run交互,那么为什么不简单地提供他们的名字,仅此而已?我的意思是,我不知道为什么你需要为内部处理的Thread提供一个名字,当你只与他们的Callable/Runnable交互的时候(假设你正在这样做)。据我所知,你可以在你的BatchFileReader实现中为名字(即一个getName)提供一个访问器方法。
https://stackoverflow.com/questions/65485100
复制相似问题