ThreadFactory newThread()方法仅在ThreadPoolExectutor

时间:2016-01-18 14:58:23

标签: java multithreading java.util.concurrent threadpoolexecutor

我正在尝试为提交给MyRunnable的{​​{1}}分配一个号码,但我没有成功。

我的代码段

ThreadPoolExecutor

我的期望:

import java.util.concurrent.*; class SimpleThreadFactory implements ThreadFactory { String name; static int threadNo = 0; public SimpleThreadFactory (String name){ this.name = name; } public Thread newThread(Runnable r) { ++threadNo; System.out.println("thread no:"+threadNo); return new Thread(r,name+":"+threadNo ); } public static void main(String args[]){ SimpleThreadFactory factory = new SimpleThreadFactory("Ravindra"); ThreadPoolExecutor executor = new ThreadPoolExecutor(1,5,10,TimeUnit.SECONDS,new ArrayBlockingQueue(100),factory); for ( int i=0; i < 10; i++){ executor.submit(new MyRunnable()); } executor.shutdown(); } } class MyRunnable implements Runnable { public void run(){ System.out.println("Runnable:"+Thread.currentThread().getName()); } } 应该在执行者的每个提交中调用ThreadFactory中的newThread。但实际上,它只发生过一次。

输出:

executor.submit(new MyRunnable());

为什么submit()没有为每个提交的Runnable任务创建新线程?

如何为提交给执行人的每个MyRunnable分配一个序列号?

提前致谢

4 个答案:

答案 0 :(得分:1)

其他答案解释了为什么没有多个线程。我关于如何实现你真正想要的东西的提议是这样的:

首先,计算runnable的实例,而不是运行它们的线程:例如像这样 - &gt;

class MyRunnable implements Runnable{
    private static long _mySequenceCounter = 0; // Maybe use an AtomicLong?
    private final long mySeqNo;

    MyRunnable(){ mySeqNo = ++_mySequenceCounter; }

// Your other stuff here

}

在run-method内部,如果满足您的要求,您可以重命名当前线程。或者您可以输出runnable id并保留Threads名称。这样做的好处就是你会知道哪个线程被重用于哪个任务...如果这对你有任何价值。

备注:上面的代码片段只是为了阐明如何满足您识别任务的要求。当然,如果你需要线程安全性,你可以改进它(如果在多个线程上创建MyRunnables,代码片段可能会有问题。)

long应该会给你很多序列号,但请注意,即使很长一段时间也会翻身。因此,如果您的应用程序运行时间很长并且新MyRunnable的频率很高,您可能希望解决此问题。

答案 1 :(得分:1)

问题是CorePoolSize和队列之间的交互。

来自Javadoc

  

“如果正在运行corePoolSize或更多线程,则执行程序始终为   更喜欢排队请求而不是添加新线程。“

  

“如果有多个corePoolSize但小于maximumPoolSize   如果线程正在运行,则只有在队列出现时才会创建新线程   完整的“。

目前,您的任务会排队,直到CorePoolSize中有空间(即当前正在执行的任务完成时),因此您当前从不使用多于1个线程。

答案 2 :(得分:1)

请参阅Core and maximum pool sizes

下的ThreadPoolExecutor JavaDoc
  

当在方法execute(java.lang.Runnable)中提交新任务时,....如果有多个corePoolSize但运行的是最多的maximumPoolSize线程,则只有队列才会创建一个新线程已满

为了让代码创建更多线程,我改变了这一点:

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                // Core pool size
                5,
                // Max pool size
                5,
                // Resize time
                1,
                // Resize time units
                TimeUnit.MILLISECONDS,
                // Queue of runnables - I CHANGED THIS TO 10
                new ArrayBlockingQueue(10),
                // Factory to use for threads.
                factory);
        for (int i = 0; i < 100; i++) {
            executor.submit(new MyRunnable());
        }

答案 3 :(得分:-1)

尝试为您的&#34;运行&#34;添加睡眠。方法:这里执行时间可能太短,不需要很多线程......