我正在尝试理解ThreadPoolExecutor类。我读过这个answer和Javadoc。但是我的实验与那种描述不符:
我使用工厂初始化线程池以跟踪ID
int tcounter = 0;
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 1, TimeUnit.MINUTES,
new ArrayBlockingQueue<Runnable>(1000), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new mThread(tcounter++, r);
}
});
public class mThread extends Thread {
int id;
private mThread(int id, Runnable run) {
super(run);
GLog.e("created thread " + id);
this.id = id;
}
}
然后任务:
public class mRunanble implements Runnable {
int value = 0;
private mRunanble(int value) {
super();
this.value = value;
}
@Override
public void run() {
SystemClock.sleep(3000);
Thread t = Thread.currentThread();
if (t instanceof mThread) {
GLog.e("Say " + (value) + " on thread " + ((mThread) t).id);
}
}
}
并为操作分配按钮:
executor.execute(new mRunanble(i++));
但我垃圾邮件那个按钮并且永远不会创建第三个线程,所以ThreadPoolExecutor构造函数(maximumPoolSize=4
)中的第二个参数是什么。
我正在编写4个线程来创建,其中2个在执行结束1分钟后被杀死
答案 0 :(得分:5)
来自ThreadPoolExecutor
的API:
如果有多个corePoolSize但小于maximumPoolSize 如果线程正在运行,则只有在队列出现时才会创建新线程 满。
您的队列永远不会填充,因为它的容量为1000
。如果您将容量更改为1
,则会看到正在创建Thread
。
Executors
类使用SynchronousQueue
作为newCachedThreadPool
方法,因此您可能也想考虑使用它。
答案 1 :(得分:2)
在ThreadPoolExecutor中,当corePoolSize no不足以执行你的任务时,maximumPoolSize会出现在图片中,如果所有no都没有被任务占用,那么只有一个步骤被创建来执行任务。这个不能增长到maxPoolSize。
编辑您误解了maxPoolsize概念。请参阅以下链接。
http://www.bigsoft.co.uk/blog/index.php/2009/11/27/rules-of-a-threadpoolexecutor-pool-size
答案 2 :(得分:0)
为了让ThreadPool创建新的附加线程(根据 maximumPoolSize 参数扩展池大小),尝试执行这个简单的例子:
public class Main {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor tpe = new ThreadPoolExecutor(
1, 2, 500, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1));
System.out.println("init pool size= " + tpe.getPoolSize() + ", queue size=" + tpe.getQueue().size());
tpe.execute(new Task("1st", 10000));
Thread.sleep(1000);
print(tpe, "1st");
tpe.execute(new Task("2nd", 0));
Thread.sleep(1000);
print(tpe, "2nd");
tpe.execute(new Task("3d", 2000));
Thread.sleep(1000);
print(tpe, "3d");
while (tpe.getPoolSize()>1) {
Thread.sleep(100);
}
System.out.println("pool size= " + tpe.getPoolSize() + ", queue size=" + tpe.getQueue().size());
tpe.shutdown();
}
private static void print(ThreadPoolExecutor tpe, String name) {
System.out.println("After " + name + " execute - pool size= " + tpe.getPoolSize() + ", queue=" + tpe.getQueue());
}
private static class Task implements Runnable {
private final String name;
private final long time;
Task(String name, long time) {
this.name = name;
this.time = time;
}
@Override
public void run() {
System.out.println("Run " + Thread.currentThread().getName() + "-" + name);
try {
Thread.sleep(time);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
System.out.println("Finish " + Thread.currentThread().getName() + "-" + name);
}
@Override
public String toString() {
return name;
}
}
}
您将获得显示 maximumPoolSize 和 keepAliveTime 影响的输出:
init pool size= 0, queue size=0
Run pool-1-thread-1-1st
After 1st execute - pool size= 1, queue=[]
After 2nd execute - pool size= 1, queue=[2nd]
Run pool-1-thread-2-3d
After 3d execute - pool size= 2, queue=[2nd]
Finish pool-1-thread-2-3d
Run pool-1-thread-2-2nd
Finish pool-1-thread-2-2nd
pool size= 1, queue size=0
Finish pool-1-thread-1-1st