【问题标题】:Multithreading - Naming threads and handling exceptions多线程 - 命名线程和处理异常
【发布时间】:2013-06-05 06:16:03
【问题描述】:

在java中,实现两个线程要求的建议方法是什么

  1. 我想要一个线程的名字
  2. 我希望父(或主)线程知道该子线程是否有任何异常。

对于 2,我 understand that 拥有一个未来的对象将是一个更好的方法。所以为了实现上面的两个要求,下面是我想出的一段代码

class MyRunnable implements Runnable {
  ....
}


MyRunnable myRunnable = new MyRunnable ();
FutureTask futureTask = new FutureTask(myRunnable, null);
Thread myThread = new MyThread(futureTask, "processing-thread");
myThread.start();
try {
   futureTask.get();
} catch (Exception e) {
   throw new RuntimeException(e)
}

这似乎是很多简单东西的代码。还有更好的方法吗?

注意 - 使用 executorService 不是一个选项,因为我有没有执行类似任务的线程。 executorService 也接受线程名称前缀而不是线程名称。我想给每个线程一个唯一的名称。

【问题讨论】:

  • 查找ThreadFactory。实现一个,您可以为从它请求的每个新线程具有唯一的命名。您还可以为 ExecutorService 提供一个,从而覆盖其命名。是什么让您认为 ExecutorService 要求任务相似?
  • @Fildor - 感谢您的回复。如何在不使用 ExecutorService 的情况下使用 ThreadFactory?顺便说一句,我认为由于 ExecutorService 默认使用“pool-1-thread-1”之类的约定命名线程,因此它用于提交类似的执行任务。如何使用 ExecutorService 提交不同的线程并为其赋予唯一的名称?

标签: java multithreading futuretask


【解决方案1】:

使用 executorService 不是一个选项,因为我有没有执行类似任务的线程。

我不明白这有什么关系。

executorService 也接受线程名称前缀而不是线程名称。我想给每个线程一个唯一的名称。

因此,给每个线程一个带有 ThreadFactory 的名称。我有一个名为 NamedThreadFactory 的类。

我怀疑你希望线程做的是反映任务正在做什么。

你可以这样做

ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new Runnable() {
    public void run() {
        Thread.currentThread().setName("Working on task A");
        try {
            System.out.println("Running: "+Thread.currentThread());
        } finally {
            Thread.currentThread().setName("parked worker thread");
        }
    }
});
es.shutdown();

打印

Running: Thread[Working on task A,5,main]

顺便说一句,启动一个线程并立即等待它完成是没有意义的。你也可以使用当前线程。

【讨论】:

  • executorService 如果未传递线程工厂实例,则按自己的约定命名线程。所以调用 Thread.currentThread().setName("my-name") 是行不通的,我猜。
  • @AndyDufresne 或者你可以试试,看看我更新的答案。就声誉而言,我在 Java 方面排名第三,并且是第一个获得 JVM 银徽章的人;)
  • 好的。我的错。有用。顺便说一句,使用 executorservice 来执行没有任何共同点或不相似的任务不是很干净吗?
  • @AndyDufresne 我会说 ExecutorService 旨在执行随机的 Runnables 和 Callables,它们之间可能没有任何关系。它旨在将可能由更多线程完成的工作聚合到更小的线程池中。
【解决方案2】:

关于命名:

ThreadFactory myFactory = new ThreadFactory(){
  @Override public Thread newThread( Runnable r ) {
       return new Thread( r, getName() )
  }

  private int number = 0;

  private String getName(){
      return "MyThread_" + (number++);
  }

}

还有其他方法。这是我个人最喜欢的。

---编辑---

要给线程完全不同的名称,我会采取另一种方式:

一种可能性是在 Runnable 中设置名称:请参阅 Peter 的回答并添加一个内容:您可以在启动 Thread 之前初始化 Runnable 实现的成员变量,而不是固定的 String。

【讨论】:

  • 请看我的编辑。在没有 Executor 的情况下使用 ThreadFactory 很简单:您调用 myThreadFactory.newThread( myRunnable) 而不是 new Thread(...
猜你喜欢
  • 2014-03-23
  • 1970-01-01
  • 2013-09-10
  • 2013-10-06
  • 2011-10-15
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
相关资源
最近更新 更多