如何为可调用线程命名?
我正在使用 ExecutorService 线程池执行可调用对象。我想给这个线程起一个名字。
更具体地说,在旧版本中我这样做了 -
Thread thread = new Thread(runnable Task);
thread.setName("My Thread Name");
我在 log4j 日志记录中使用线程名称,这在故障排除时有很大帮助。现在我正在将代码从 Java 1.4 迁移到 Java 1.6。我已经写了这个(如下)-但我不知道如何给这个线程命名。
private final ExecutorService executorPool = Executors.newCachedThreadPool();
Future<String> result = executorPool.submit(callable Task);
请给我一些想法来给这个线程命名?
I am executing a Callable Object using ExecutorService thread pool. I want to give a name to this thread.
To be more specific, in older version I did this -
Thread thread = new Thread(runnable Task);
thread.setName("My Thread Name");
I use thread name in log4j logging, this helps a lot while troubleshooting. Now I am migrating my code from Java 1.4 to Java 1.6. I have written this(Given below)- but I dont know how to give name to this thread.
private final ExecutorService executorPool = Executors.newCachedThreadPool();
Future<String> result = executorPool.submit(callable Task);
Please give me some idea to give name to this thread?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我目前正在这样做:
I'm currently doing it somewhat like this:
您可以使用重载方法:
它允许您传递一个
允许您通过 java.util.concurrent.ThreadFactory.newThread(Runnable) 设置线程名称的方法:
请查看 java.util.concurrent.Executors.DefaultThreadFactory 以了解默认实现。
附录
由于我发现该线程仍然被访问,Guava(如果有的话)提供了ThreadFactoryBuilder 利用了内部匿名类的需求,甚至允许为您的自定义参数化名称线程。
You may use the overloaded method:
which allows you to pass a
that should allow you to set the thread's names via
java.util.concurrent.ThreadFactory.newThread(Runnable)
:Have a look at
java.util.concurrent.Executors.DefaultThreadFactory
for a default implementation.Addendum
Since I see that this thread is still visited, Guava (if you have it available) provides a ThreadFactoryBuilder that leverages the need of having an inner anonymous class and even allows for customizing parametrized names for your threads.
这是 Java 1.5.0 中的原始实现。因此,实际上名称为 pool-x-thread,其中 x 代表当前线程组中线程的顺序。
This is the original implementation in Java 1.5.0. So, you actually have the names as pool-x-thread where x stands for the order of the thread in the current thread group.
当线程由线程池管理时,重命名线程时应该小心,因为它们实际上会一遍又一遍地重复用于不同的任务,并且一旦重命名,您可能会发现日志中的线程名称没有任何意义...为了避免这种不需要的行为,您应该确保一旦您的 Runnable/Callable 完成,线程名称就会恢复。
实现此目的的一种方法是使用装饰器包装线程池执行的每个 Runnable/Callable,该装饰器处理所有需要的清理工作。
You should be careful when renaming threads when your threads are managed by a thread-pool because they are actually being reused over and over again for different tasks and once renamed, you might find that the thread names in your logs don't make any sense... In order to avoid that unwanted behavior you should make sure that once your Runnable/Callable finished the thread name is restored.
One way to implement this is by wrapping every Runnable/Callable that is executed by the thread-pool with a decorator which handles all of the needed clean-ups.
如果您使用 Spring,则可以使用 org.springframework.scheduling.concurrent.CustomizedThreadFactory 为此:
If you are using Spring, you may use org.springframework.scheduling.concurrent.CustomizableThreadFactory for that:
我只需要做你所要求的——为我的线程组提供名称——所以感谢 Andeas 的回答,我创建了自己的 ThreadFactory 作为将要通过复制 Executors$DefaultThreadFactory 来使用它的类的内部类,通过将参数“groupname”添加到构造函数来更改 3 行。
从它创建一个线程池的过程如下。
感谢 user381878 提出问题,感谢 Andreas 的回答。
I just had to do what you are asking for -- providing names to my thread groups -- so thanks to Andeas's answer, I created my own ThreadFactory as an inner-class to the class that is going to use it by copying Executors$DefaultThreadFactory, changing 3 lines by adding the parameter "groupname" to the constructor.
Creating a ThreadPool from it is done as follows.
Thanks user381878 for asking the question, and Andreas for the answer.
只需创建一个匿名ThreadFactory来获取Executor Service即可。
ThreadFactory 可以提供线程的名称,如下所示:“Thread A”或“Thread B”(请参见示例)。
然后使用不同的执行器服务调用可调用任务:
示例类:
public class ThreadTester {
}
Callable Task :
public class CallableTask Implements Callable {
}
Just create an anonymous ThreadFactory for getting the Executor Service.
The ThreadFactory can supply the name for the thread as follows: "Thread A" or "Thread B" (see the example).
Then call the callable task using the different executor services:
Example Class:
public class ThreadTester {
}
Callable Task :
public class CallableTask implements Callable {
}
我使用过的一种方法,在我的例子中,我有多个由单个类控制的并行获取数据的 future。我提交了一些工作并拿回了期货。我将未来存储在地图中,并将值作为作业名称。
然后,当我对所有 future 进行超时处理时,我从地图上得到了作业的名称。这可能不是最灵活的方式,但在我的情况下有效。
One approach that I've used, and in my case I had a number of futures fetching data in parallel controlled by a single class. I submit a number of jobs and get the futures back. I store the future in a map with the value as the job name.
Then later on, when I'm doing a get with a timeout on all futures I have the name of the job from the map. It's not maybe the most flexible way but worked in my situation.