267

Executorフレームワーク自体を利用するアプリケーションがあるとしましょう

Executors.newSingleThreadExecutor().submit(new Runnable(){
    @Override
    public void run(){
        // do stuff
    }
}

このアプリケーションをデバッガーで実行すると、次の (既定の) 名前でスレッドが作成されます: Thread[pool-1-thread-1]. ご覧のとおり、これはあまり役に立ちません。私が知る限り、Executorフレームワークは、作成されたスレッドまたはスレッドプールに名前を付ける簡単な方法を提供していません。

では、スレッド/スレッドプールに名前を付けるにはどうすればよいでしょうか? たとえば、Thread[FooPool-FooThread].

4

20 に答える 20

313

グアバはほとんどの場合、必要なものを持っています。

ThreadFactory namedThreadFactory = 
  new ThreadFactoryBuilder().setNameFormat("my-sad-thread-%d").build()

そしてそれをあなたに渡しますExecutorService

于 2012-03-17T09:06:32.847 に答える
133

ThreadFactorytoを指定できnewSingleThreadScheduledExecutor(ThreadFactory threadFactory)ます。ファクトリはスレッドの作成を担当し、それらに名前を付けることができます。

Javadocを引用するには:

新しいスレッドの作成

を使用して新しいスレッドが作成されThreadFactoryます。特に指定されていない場合は、aExecutors.defaultThreadFactory()が使用されます。これにより、スレッドはすべて同じThreadGroupになり、同じNORM_PRIORITY優先度と非デーモン ステータスになります。別ThreadFactoryの を指定することで、スレッドの名前、スレッド グループ、優先順位、デーモン ステータスなどを変更できますThreadFactorynewThread

于 2011-05-24T16:38:34.397 に答える
104

適切な名前のスレッドを作成する独自のスレッド ファクトリを提供することができます。一例を次に示します。

class YourThreadFactory implements ThreadFactory {
   public Thread newThread(Runnable r) {
     return new Thread(r, "Your name");
   }
 }

Executors.newSingleThreadExecutor(new YourThreadFactory()).submit(someRunnable);

またはコトリンで

Executors.newSingleThreadExecutor { r -> Thread(r, "Your name") }
于 2011-05-24T16:38:07.383 に答える
55

BasicThreadFactoryfrom apache commons-lang も、ネーミング動作を提供するのに役立ちます。匿名の内部クラスを作成する代わりに、Builder を使用して必要に応じてスレッドに名前を付けることができます。javadocs の例を次に示します。

 // Create a factory that produces daemon threads with a naming pattern and
 // a priority
 BasicThreadFactory factory = new BasicThreadFactory.Builder()
     .namingPattern("workerthread-%d")
     .daemon(true)
     .priority(Thread.MAX_PRIORITY)
     .build();
 // Create an executor service for single-threaded execution
 ExecutorService exec = Executors.newSingleThreadExecutor(factory);
于 2011-05-25T14:45:53.017 に答える
39

Spring を使用している場合はCustomizableThreadFactory、スレッド名のプレフィックスを設定できるものがあります。

例:

ExecutorService alphaExecutor =
    Executors.newFixedThreadPool(10, new CustomizableThreadFactory("alpha-"));

ExecutorServiceまたは、 Spring Bean を使用して作成することもできますThreadPoolExecutorFactoryBean- すると、スレッドはすべてbeanName-接頭辞で名前が付けられます。

@Bean
public ThreadPoolExecutorFactoryBean myExecutor() {
    ThreadPoolExecutorFactoryBean executorFactoryBean = new ThreadPoolExecutorFactoryBean();
    // configuration of your choice
    return executorFactoryBean;
}

上記の例では、スレッドにはmyExecutor-接頭辞が付いた名前が付けられます。ファクトリ Bean で設定することにより、接頭辞を明示的に別の値 (例: "myPool-") に設定できます。executorFactoryBean.setThreadNamePrefix("myPool-")

于 2016-01-07T08:13:59.217 に答える
27

これについては、Oracle とのオープンな RFEがあります。オラクルの従業員からのコメントによると、彼らは問題を理解しておらず、修正しないようです。これは、JDK でサポートするのが非常に簡単な (後方互換性を損なうことなく) これらのことの 1 つであるため、RFE が誤解されるのはちょっと残念です。

指摘したように、独自のThreadFactoryを実装する必要があります。この目的のためだけに Guava または Apache Commons を取り込みたくない場合は、ここでThreadFactory使用できる実装を提供します。これは、スレッド名のプレフィックスを「プール」以外に設定できることを除いて、JDK から得られるものとまったく同じです。

package org.demo.concurrency;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * ThreadFactory with the ability to set the thread name prefix. 
 * This class is exactly similar to 
 * {@link java.util.concurrent.Executors#defaultThreadFactory()}
 * from JDK8, except for the thread naming feature.
 *
 * <p>
 * The factory creates threads that have names on the form
 * <i>prefix-N-thread-M</i>, where <i>prefix</i>
 * is a string provided in the constructor, <i>N</i> is the sequence number of
 * this factory, and <i>M</i> is the sequence number of the thread created 
 * by this factory.
 */
public class ThreadFactoryWithNamePrefix implements ThreadFactory {

    // Note:  The source code for this class was based entirely on 
    // Executors.DefaultThreadFactory class from the JDK8 source.
    // The only change made is the ability to configure the thread
    // name prefix.


    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    /**
     * Creates a new ThreadFactory where threads are created with a name prefix
     * of <code>prefix</code>.
     *
     * @param prefix Thread name prefix. Never use a value of "pool" as in that
     *      case you might as well have used
     *      {@link java.util.concurrent.Executors#defaultThreadFactory()}.
     */
    public ThreadFactoryWithNamePrefix(String prefix) {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup()
                : Thread.currentThread().getThreadGroup();
        namePrefix = prefix + "-"
                + poolNumber.getAndIncrement()
                + "-thread-";
    }


    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                namePrefix + threadNumber.getAndIncrement(),
                0);
        if (t.isDaemon()) {
            t.setDaemon(false);
        }
        if (t.getPriority() != Thread.NORM_PRIORITY) {
            t.setPriority(Thread.NORM_PRIORITY);
        }
        return t;
    }
}

それを使用したい場合は、すべてのExecutorsメソッドで独自の を提供できるという事実を利用するだけThreadFactoryです。

これ

    Executors.newSingleThreadExecutor();

pool-N-thread-Mスレッドに名前が付けられている ExecutorService を提供しますが、

    Executors.newSingleThreadExecutor(new ThreadFactoryWithNamePrefix("primecalc"));

スレッドの名前が付けられている ExecutorService を取得しますprimecalc-N-thread-M。出来上がり!

于 2015-05-16T18:52:16.340 に答える
9

手っ取り早い方法はThread.currentThread().setName(myName);run()メソッドで使用することです。

于 2014-07-18T07:46:09.413 に答える
8

ThreadFactory の拡張

public interface ThreadFactory

オンデマンドで新しいスレッドを作成するオブジェクト。スレッド ファクトリを使用すると、新しい Thread への呼び出しの配線が取り除かれ、アプリケーションが特別なスレッド サブクラスや優先順位などを使用できるようになります。

Thread newThread(Runnable r)

新しいスレッドを構築します。実装は、優先度、名前、デーモンのステータス、ThreadGroup などを初期化することもできます。

サンプルコード:

import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

import java.util.concurrent.ThreadPoolExecutor.DiscardPolicy;

class SimpleThreadFactory implements ThreadFactory {
   String name;
   AtomicInteger threadNo = new AtomicInteger(0);

   public SimpleThreadFactory (String name){
       this.name = name;
   }
   public Thread newThread(Runnable r) {
     String threadName = name+":"+threadNo.incrementAndGet();
     System.out.println("threadName:"+threadName);
     return new Thread(r,threadName );
   }
   public static void main(String args[]){
        SimpleThreadFactory factory = new SimpleThreadFactory("Factory Thread");
        ThreadPoolExecutor executor= new ThreadPoolExecutor(1,1,60,
                    TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1),new ThreadPoolExecutor.DiscardPolicy());


        final ExecutorService executorService = Executors.newFixedThreadPool(5,factory);

        for ( int i=0; i < 100; i++){
            executorService.submit(new Runnable(){
                 public void run(){
                    System.out.println("Thread Name in Runnable:"+Thread.currentThread().getName());
                 }
            });
        }
        executorService.shutdown();
    }
 }

出力:

java SimpleThreadFactory

thread no:1
thread no:2
Thread Name in Runnable:Factory Thread:1
Thread Name in Runnable:Factory Thread:2
thread no:3
thread no:4
Thread Name in Runnable:Factory Thread:3
Thread Name in Runnable:Factory Thread:4
thread no:5
Thread Name in Runnable:Factory Thread:5

....等

于 2016-02-05T15:59:16.897 に答える
4
Executors.newSingleThreadExecutor(r -> new Thread(r, "someName")).submit(getJob());

Runnable getJob() {
        return () -> {
            // your job
        };
}
于 2016-12-03T23:25:22.087 に答える