อะไรคือความแตกต่างระหว่างขนาดของคอร์พูลและขนาดพูลสูงสุดเมื่อเราพูดถึงThreadPoolExecutor
?
สามารถอธิบายได้ด้วยความช่วยเหลือของตัวอย่างหรือไม่?
อะไรคือความแตกต่างระหว่างขนาดของคอร์พูลและขนาดพูลสูงสุดเมื่อเราพูดถึงThreadPoolExecutor
?
สามารถอธิบายได้ด้วยความช่วยเหลือของตัวอย่างหรือไม่?
คำตอบ:
จากบล็อกโพสต์นี้ :
ใช้ตัวอย่างนี้ เธรดพูลเริ่มต้นคือ 1 ขนาดพูลแกนคือ 5 ขนาดพูลสูงสุดคือ 10 และคิวคือ 100
ในฐานะที่ร้องขอมาในหัวข้อจะถูกสร้างขึ้นถึง 5 และงานที่จะถูกเพิ่มลงในคิวจนกว่าจะถึง 100
maxPoolSize
เมื่อคิวเต็มหัวข้อใหม่จะถูกสร้างขึ้นมาเพื่อ เมื่อเธรดทั้งหมดถูกใช้งานและคิวเป็นงานทั้งหมดจะถูกปฏิเสธ เมื่อคิวลดจำนวนเธรดที่ใช้งานอยู่ก็จะลดลง
allowCoreThreadTimeOut(boolean)
ซึ่งช่วยให้เธรดหลักถูกฆ่าหลังจากเวลาว่างที่กำหนด การตั้งค่านี้เพื่อความจริงและการตั้งค่าcore threads
= max threads
ช่วยให้สระว่ายน้ำด้ายขนาดระหว่าง 0 max threads
และ
หากรันเธรด> corePoolSize & <maxPoolSizeจากนั้นสร้างเธรดใหม่หากคิวงานทั้งหมดเต็มและมีอันใหม่มาถึง
แบบฟอร์ม doc: (หากมีเธรด corePoolSizeมากกว่าแต่น้อยกว่าmaximumPoolSizeเธรดที่รันเธรดใหม่จะถูกสร้างขึ้นก็ต่อเมื่อคิวเต็มเท่านั้น)
ยกตัวอย่างง่ายๆ
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(5, 10, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50));
ที่นี่ 5 คือ corePoolSize - หมายความว่าJvmจะสร้างเธรดใหม่สำหรับงานใหม่สำหรับ 5 งานแรก และงานอื่น ๆ จะถูกเพิ่มลงในคิวจนกว่าคิวจะเต็ม (50 งาน)
10 คือ maxPoolSize - JVM สามารถสร้างเธรดได้สูงสุด 10 เธรด หมายถึงถ้ามีงาน / เธรด 5 รายการกำลังทำงานอยู่และคิวเต็มโดยมีงานที่รอดำเนินการ 50 งานและหากมีคำขอ / งานใหม่อีกหนึ่งรายการเข้ามาในคิว JVM จะสร้างเธรดใหม่สูงสุด 10 (เธรดทั้งหมด = ก่อนหน้า 5 + ใหม่ 5) ;
ใหม่ ArrayBlockingQueue (50) = คือขนาดคิวทั้งหมด - สามารถจัดคิวงานได้ 50 งาน
เมื่อเธรดทั้ง 10 กำลังทำงานและหากมีงานใหม่มาถึงงานใหม่นั้นจะถูกปฏิเสธ
กฎสำหรับการสร้างเธรดภายในโดย SUN:
หากจำนวนเธรดน้อยกว่า corePoolSize ให้สร้าง Thread ใหม่เพื่อรันงานใหม่
ถ้าจำนวนเธรดเท่ากับ (หรือมากกว่า) corePoolSize ให้ใส่งานลงในคิว
หากคิวเต็มและจำนวนเธรดน้อยกว่า maxPoolSize ให้สร้างเธรดใหม่เพื่อรันงาน
หากคิวเต็มและจำนวนเธรดมากกว่าหรือเท่ากับ maxPoolSize ให้ปฏิเสธงาน
หวังว่านี่คือ HelpFul .. และโปรดแก้ไขฉันถ้าฉันผิด ...
จากเอกสาร :
เมื่องานใหม่ถูกส่งใน method execute (java.lang.Runnable) และมีเธรด corePoolSize น้อยกว่ากำลังรันเธรดใหม่จะถูกสร้างขึ้นเพื่อจัดการกับคำร้องขอแม้ว่าเธรดผู้ปฏิบัติงานอื่นจะไม่ได้ใช้งานก็ตาม หากมีเธรด corePoolSize มากกว่า แต่น้อยกว่า maximumPoolSize เธรดที่รันเธรดใหม่จะถูกสร้างขึ้นก็ต่อเมื่อคิวเต็ม
นอกจากนี้:
โดยการตั้งค่า corePoolSize และ maximumPoolSize เหมือนกันคุณจะสร้างเธรดพูลขนาดคงที่ โดยการตั้งค่า maximumPoolSize เป็นค่าที่ไม่ถูกผูกมัดเช่น Integer.MAX_VALUE คุณอนุญาตให้พูลรองรับจำนวนงานพร้อมกันโดยพลการ โดยทั่วไปขนาดคอร์และพูลสูงสุดจะถูกกำหนดตามการก่อสร้างเท่านั้น แต่อาจมีการเปลี่ยนแปลงแบบไดนามิกโดยใช้ setCorePoolSize (int) และ setMaximumPoolSize (int)
หากคุณตัดสินใจที่จะสร้างThreadPoolExecutor
ด้วยตนเองแทนที่จะใช้Executors
คลาสโรงงานคุณจะต้องสร้างและกำหนดค่าโดยใช้ตัวสร้างตัวใดตัวหนึ่ง ตัวสร้างที่ครอบคลุมที่สุดของคลาสนี้คือ:
public ThreadPoolExecutor(
int corePoolSize,
int maxPoolSize,
long keepAlive,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler
);
อย่างที่คุณเห็นคุณสามารถกำหนดค่า:
การ จำกัด จำนวนงานที่ดำเนินการพร้อมกันที่กำลังดำเนินการปรับขนาดเธรดพูลของคุณแสดงให้เห็นถึงประโยชน์อย่างมากสำหรับแอปพลิเคชันของคุณและสภาพแวดล้อมการดำเนินการในแง่ของความสามารถในการคาดเดาและความเสถียร: การสร้างเธรดที่ไม่มีขอบเขตจะทำให้ทรัพยากรรันไทม์หมดลงในที่สุดและแอปพลิเคชันของคุณอาจประสบผล ปัญหาด้านประสิทธิภาพที่ร้ายแรงซึ่งอาจนำไปสู่ความไม่แน่นอนของแอปพลิเคชัน
นั่นเป็นวิธีแก้ปัญหาเพียงส่วนเดียว: คุณกำหนดจำนวนงานที่กำลังดำเนินการ แต่ไม่ได้กำหนดจำนวนงานที่สามารถส่งและจัดคิวเพื่อดำเนินการในภายหลังได้ แอปพลิเคชันจะประสบปัญหาการขาดแคลนทรัพยากรในภายหลัง แต่จะพบได้ในที่สุดหากอัตราการส่งข้อมูลสูงกว่าอัตราการดำเนินการอย่างต่อเนื่อง
วิธีแก้ปัญหานี้คือ: จัดเตรียมคิวการบล็อกให้กับผู้ดำเนินการเพื่อเก็บงานที่รออยู่ ในกรณีที่คิวเต็มงานที่ส่งจะถูก "ปฏิเสธ" RejectedExecutionHandler
จะเรียกเมื่อส่งงานถูกปฏิเสธและว่าทำไมคำกริยาปฏิเสธอ้างในรายการก่อนหน้า คุณสามารถใช้นโยบายการปฏิเสธของคุณเองหรือใช้นโยบายในตัวที่มีให้โดยกรอบงาน
นโยบายการปฏิเสธเริ่มต้นมีผู้ปฏิบัติการโยนไฟล์RejectedExecutionException
. อย่างไรก็ตามนโยบายในตัวอื่น ๆ ช่วยให้คุณ:
กฎของขนาดพูล ThreadPoolExecutor
โดยทั่วไปกฎสำหรับขนาดของThreadPoolExecutor's
พูลนั้นมักจะเข้าใจผิดเพราะมันไม่ได้ผลในแบบที่คุณคิดว่าควรจะเป็นหรือในแบบที่คุณต้องการ
ใช้ตัวอย่างนี้ เธรดพูลเริ่มต้นคือ 1 ขนาดพูลแกนคือ 5 ขนาดพูลสูงสุดคือ 10 และคิวคือ 100
ทางดวงอาทิตย์: การร้องขอมาในหัวข้อจะถูกสร้างขึ้นถึง 5 งานแล้วจะถูกเพิ่มลงในคิวจนกว่าจะถึง 100 maxPoolSize
เมื่อคิวเต็มหัวข้อใหม่จะถูกสร้างขึ้นมาเพื่อ เมื่อเธรดทั้งหมดถูกใช้งานและคิวเป็นงานทั้งหมดจะถูกปฏิเสธ เนื่องจากคิวจะลดจำนวนเธรดที่ใช้งานอยู่
วิธีที่ผู้ใช้คาดหวัง: เนื่องจากคำขอเข้ามาในเธรดจะถูกสร้างขึ้นสูงสุด 10 รายการจากนั้นงานจะถูกเพิ่มลงในคิวจนกว่าจะถึง 100 ณ จุดที่พวกเขาถูกปฏิเสธ จำนวนเธรดจะเปลี่ยนชื่อสูงสุดจนกว่าคิวจะว่างเปล่า เมื่อคิวว่างเธรดจะตายจนกว่าจะcorePoolSize
เหลือ
ความแตกต่างคือผู้ใช้ต้องการเริ่มเพิ่มขนาดพูลก่อนหน้านี้และต้องการให้คิวมีขนาดเล็กลงโดยที่วิธีการของ Sun ต้องการให้ขนาดพูลมีขนาดเล็กและเพิ่มขึ้นก็ต่อเมื่อโหลดมากขึ้นเท่านั้น
นี่คือกฎของ Sun สำหรับการสร้างเธรดในแง่ง่ายๆ:
corePoolSize
สร้างเธรดใหม่เพื่อรันงานใหม่corePoolSize
ใส่งานลงในคิวmaxPoolSize
สร้างเธรดใหม่เพื่อรันงานmaxPoolSize
ปฏิเสธงาน corePoolSize
ยาวและระยะสั้นของมันคือหัวข้อใหม่จะถูกสร้างขึ้นเฉพาะเมื่อคิวเติมขึ้นดังนั้นหากคุณกำลังใช้คิวมากมายแล้วจำนวนกระทู้จะไม่เกินหากต้องการคำอธิบายที่สมบูรณ์ยิ่งขึ้นโปรดอ่านจากปากม้า: ThreadPoolExecutor
เอกสาร API
มีโพสต์ในฟอรัมที่ดีมากซึ่งพูดถึงวิธีการThreadPoolExecutor
ทำงานกับตัวอย่างโค้ด: http://forums.sun.com/thread.jspa?threadID=5401400&tstart=0
ข้อมูลเพิ่มเติม: http://forums.sun.com/thread.jspa?threadID=5224557&tstart=450
คุณสามารถค้นหาคำจำกัดความของคำว่า corepoolsize และ maxpoolsize ได้ใน javadoc http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
ลิงก์ด้านบนมีคำตอบสำหรับคำถามของคุณ อย่างไรก็ตามเพียงเพื่อให้ชัดเจน แอปพลิเคชันจะสร้างเธรดต่อไปจนกว่าจะถึง corePoolSize ฉันคิดว่าแนวคิดในที่นี้คือเธรดจำนวนมากเหล่านี้ควรเพียงพอที่จะรองรับการไหลเข้าของงาน หากงานใหม่เกิดขึ้นหลังจากสร้างเธรด corePoolSize งานจะถูกจัดคิว เมื่อคิวเต็มแล้วตัวดำเนินการจะเริ่มสร้างเธรดใหม่ เป็นการสร้างสมดุล ความหมายโดยพื้นฐานคือการไหลเข้าของงานมากกว่าความสามารถในการประมวลผล ดังนั้นผู้ดำเนินการจะเริ่มสร้างเธรดใหม่อีกครั้งจนกว่าจะถึงจำนวนเธรดสูงสุด อีกครั้งเธรดใหม่จะถูกสร้างขึ้นในกรณีที่คิวเต็มเท่านั้น
คำอธิบายที่ดีในบล็อกนี้ :
public class ThreadPoolExecutorExample {
public static void main (String[] args) {
createAndRunPoolForQueue(new ArrayBlockingQueue<Runnable>(3), "Bounded");
createAndRunPoolForQueue(new LinkedBlockingDeque<>(), "Unbounded");
createAndRunPoolForQueue(new SynchronousQueue<Runnable>(), "Direct hand-off");
}
private static void createAndRunPoolForQueue (BlockingQueue<Runnable> queue,
String msg) {
System.out.println("---- " + msg + " queue instance = " +
queue.getClass()+ " -------------");
ThreadPoolExecutor e = new ThreadPoolExecutor(2, 5, Long.MAX_VALUE,
TimeUnit.NANOSECONDS, queue);
for (int i = 0; i < 10; i++) {
try {
e.execute(new Task());
} catch (RejectedExecutionException ex) {
System.out.println("Task rejected = " + (i + 1));
}
printStatus(i + 1, e);
}
e.shutdownNow();
System.out.println("--------------------\n");
}
private static void printStatus (int taskSubmitted, ThreadPoolExecutor e) {
StringBuilder s = new StringBuilder();
s.append("poolSize = ")
.append(e.getPoolSize())
.append(", corePoolSize = ")
.append(e.getCorePoolSize())
.append(", queueSize = ")
.append(e.getQueue()
.size())
.append(", queueRemainingCapacity = ")
.append(e.getQueue()
.remainingCapacity())
.append(", maximumPoolSize = ")
.append(e.getMaximumPoolSize())
.append(", totalTasksSubmitted = ")
.append(taskSubmitted);
System.out.println(s.toString());
}
private static class Task implements Runnable {
@Override
public void run () {
while (true) {
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
break;
}
}
}
}
}
เอาท์พุต:
---- Bounded queue instance = class java.util.concurrent.ArrayBlockingQueue -------------
poolSize = 1, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 3, maximumPoolSize = 5, totalTasksSubmitted = 1
poolSize = 2, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 3, maximumPoolSize = 5, totalTasksSubmitted = 2
poolSize = 2, corePoolSize = 2, queueSize = 1, queueRemainingCapacity = 2, maximumPoolSize = 5, totalTasksSubmitted = 3
poolSize = 2, corePoolSize = 2, queueSize = 2, queueCapacity = 1, maximumPoolSize = 5, totalTasksSubmitted = 4
poolSize = 2, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 5
poolSize = 3, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 6
poolSize = 4, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 7
poolSize = 5, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 8
Task rejected = 9
poolSize = 5, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 9
Task rejected = 10
poolSize = 5, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 10
--------------------
---- Unbounded queue instance = class java.util.concurrent.LinkedBlockingDeque -------------
poolSize = 1, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 2147483647, maximumPoolSize = 5, totalTasksSubmitted = 1
poolSize = 2, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 2147483647, maximumPoolSize = 5, totalTasksSubmitted = 2
poolSize = 2, corePoolSize = 2, queueSize = 1, queueRemainingCapacity = 2147483646, maximumPoolSize = 5, totalTasksSubmitted = 3
poolSize = 2, corePoolSize = 2, queueSize = 2, queueRemainingCapacity = 2147483645, maximumPoolSize = 5, totalTasksSubmitted = 4
poolSize = 2, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 2147483644, maximumPoolSize = 5, totalTasksSubmitted = 5
poolSize = 2, corePoolSize = 2, queueSize = 4, queueRemainingCapacity = 2147483643, maximumPoolSize = 5, totalTasksSubmitted = 6
poolSize = 2, corePoolSize = 2, queueSize = 5, queueRemainingCapacity = 2147483642, maximumPoolSize = 5, totalTasksSubmitted = 7
poolSize = 2, corePoolSize = 2, queueSize = 6, queueRemainingCapacity = 2147483641, maximumPoolSize = 5, totalTasksSubmitted = 8
poolSize = 2, corePoolSize = 2, queueSize = 7, queueRemainingCapacity = 2147483640, maximumPoolSize = 5, totalTasksSubmitted = 9
poolSize = 2, corePoolSize = 2, queueSize = 8, queueRemainingCapacity = 2147483639, maximumPoolSize = 5, totalTasksSubmitted = 10
--------------------
---- Direct hand-off queue instance = class java.util.concurrent.SynchronousQueue -------------
poolSize = 1, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 1
poolSize = 2, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 2
poolSize = 3, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 3
poolSize = 4, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 4
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 5
Task rejected = 6
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 6
Task rejected = 7
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 7
Task rejected = 8
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 8
Task rejected = 9
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 9
Task rejected = 10
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 10
--------------------
Process finished with exit code 0
จากหนังสือJava concurency Essentials :
CorePoolSize : ThreadPoolExecutor มีแอตทริบิวต์ corePoolSize ที่กำหนดจำนวนเธรดที่จะเริ่มทำงานจนกว่าเธรดใหม่จะเริ่มต้นเมื่อคิวเต็มเท่านั้น
MaximumPoolSize : แอตทริบิวต์นี้กำหนดจำนวนเธรดที่เริ่มต้นที่ค่าสูงสุด คุณสามารถตั้งค่านี้เป็นจำนวนเต็ม MAX_VALUE เพื่อที่จะไม่มีขอบเขตบน
java.util.concurrent.ThreadPoolExecutor
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
การทำความเข้าใจพฤติกรรมภายในของThreadPoolExecutor
เวลาที่ส่งงานใหม่ช่วยให้ฉันเข้าใจว่าอย่างไรcorePoolSize
และmaximumPoolSize
แตกต่างกันอย่างไร
ปล่อย:
N
เป็นจำนวนเธรดในพูล, getPoolSize()
. เธรดที่ใช้งานอยู่ + เธรดที่ไม่ได้ใช้งานT
เป็นจำนวนงานที่ส่งไปยังผู้ดำเนินการ / พูลC
getCorePoolSize()
มีขนาดสระว่ายน้ำหลัก วิธีการหลายหัวข้อที่มากที่สุดสามารถถูกสร้างขึ้นต่อสระว่ายน้ำสำหรับงานที่เข้ามาก่อนงานใหม่ไปที่คิวM
getMaximumPoolSize()
สระว่ายน้ำมีขนาดสูงสุด จำนวนเธรดสูงสุดที่พูลสามารถจัดสรรได้ลักษณะการทำงานของThreadPoolExecutor
Java เมื่อส่งงานใหม่:
N <= C
เธรดที่ไม่ได้ใช้งานจะไม่ได้รับมอบหมายงานขาเข้าใหม่ แต่จะสร้างเธรดใหม่แทนN > C
และถ้ามีเธรดที่ไม่ได้ใช้งานงานใหม่จะถูกกำหนดที่นั่นN > C
และถ้าไม่มีเธรดที่ไม่ได้ใช้งานงานใหม่จะถูกใส่ลงในคิว ไม่มีการสร้างเธรดใหม่ที่นี่M
เราจะสร้างหัวข้อใหม่ได้ถึง หากM
ถึงแล้วเราปฏิเสธงาน สิ่งสำคัญที่ห้ามพลาดคือห้ามสร้างเธรดใหม่จนกว่าคิวจะเต็ม!แหล่งที่มา:
corePoolSize = 0
และmaximumPoolSize = 10
ความจุคิวเป็น50
.ซึ่งจะส่งผลให้มีเธรดเดียวที่ใช้งานอยู่ในพูลจนกว่าคิวจะมี 50 รายการในนั้น
executor.execute(task #1):
before task #1 submitted to executor: java.util.concurrent.ThreadPoolExecutor@c52dafe[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
after task #1 submitted to executor: java.util.concurrent.ThreadPoolExecutor@c52dafe[Running, pool size = 1, active threads = 1, queued tasks = 1, completed tasks = 0]
[task #1 immediately queued and kicked in b/c the very first thread is created when `workerCountOf(recheck) == 0`]
execute(task #2):
before task #2 submitted to executor: java.util.concurrent.ThreadPoolExecutor@c52dafe[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
after task #2 submitted to executor: java.util.concurrent.ThreadPoolExecutor@c52dafe[Running, pool size = 1, active threads = 1, queued tasks = 1, completed tasks = 0]
[task #2 not starting before #1 is done]
... executed a few tasks...
execute(task #19)
before task #19 submitted to executor: java.util.concurrent.ThreadPoolExecutor@735afe38[Running, pool size = 1, active threads = 1, queued tasks = 17, completed tasks = 0]
after task #19 submitted to executor: java.util.concurrent.ThreadPoolExecutor@735afe38[Running, pool size = 1, active threads = 1, queued tasks = 18, completed tasks = 0]
...
execute(task #51)
before task submitted to executor: java.util.concurrent.ThreadPoolExecutor@735afe38[Running, pool size = 1, active threads = 1, queued tasks = 50, completed tasks = 0]
after task submitted to executor: java.util.concurrent.ThreadPoolExecutor@735afe38[Running, pool size = 2, active threads = 2, queued tasks = 50, completed tasks = 0]
Queue is full.
A new thread was created as the queue was full.
corePoolSize = 10
และmaximumPoolSize = 10
ความจุคิวเป็น50
.ซึ่งจะส่งผลให้มีเธรดที่ใช้งาน 10 เธรดในพูล เมื่อคิวมี 50 รายการในนั้นงานจะถูกปฏิเสธ
execute(task #1)
before task #1 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
after task #1 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
execute(task #2)
before task #2 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
after task #2 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]
execute(task #3)
before task #3 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]
after task #3 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
... executed a few tasks...
execute(task #11)
before task #11 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 10, active threads = 10, queued tasks = 0, completed tasks = 0]
after task #11 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 10, active threads = 10, queued tasks = 1, completed tasks = 0]
... executed a few tasks...
execute(task #51)
before task #51 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 10, active threads = 10, queued tasks = 50, completed tasks = 0]
Task was rejected as we have reached `maximumPoolSize`.