我正在尝试为提交给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分配一个序列号?
提前致谢
答案 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;添加睡眠。方法:这里执行时间可能太短,不需要很多线程......