Multi Threading - What is ThreadPool and how it works internally?
[ answered ]

قبل از اینکه در مورد پیاده‌سازی تردپول صحبت بشه، بهتره از کاربردش صحبت کرد. کاربرد تردپول توی جاهایی هست که قرار هست تسک‌ها با تعداد محدودی ترد انجام بشن. دلیل اینکه از یه تعداد محدود ترد استفاده میشه اینه که ساخت ترد جدید برای انجام دادن هر تسک سربار پرفورمنسی داره و اینکه هر ترد توی حافظه یه فضایی رو اشغال میکنه و نمیشه بینهایت ترد ساخت.

برای پیاده‌سازی تردپول از ساختمان داده‌ی BlockingQueue استفاده میشه. پیاده‌سازی تردپول دو بخش داره:

بخش اول- کلاس ThreadPool برای ارتباط با تردپول استفاده میشه، داخلش متدهایی مثل execute برای اجرا کردن تسک‌ها یا stop برای متوقف کردن کل تردپول هست

بخش دوم- کلاس PoolThread که پیاده‌سازی تردهای داخل تردپول هست .

برای اجرا کردن یه تسک (تسک‌ها یه آبجکت از نوع Runnable هستند) متد execute کلاس ThreadPool صدا زده میشه. این متد تسک رو توی صف قرار میده (enqueue) و اون تسک متنظر متد تا توسط یه ترد برداشته (dequeue) و اجرا بشه.

هر تردی که بیکار بود، تسک رو از توی صف برمیداره و اجراش میکنه. کد این قضیه داخل متد Run در کلاس PoolThread هست. بعد اینکه تسک انجام شد، ترد دوباره منتظر میشه تا تسک جدیدی توی صف گذاشته و بتونه برش داره. درواقع انتظار برای تسک جدید، برداشتن تسک، انجام دادن و انتظار دوباره برای تسک دیگه تا زمانی که فلگ isStopped ست نشده باشه ادامه داره. وقتی ترد stop بشه این حلقه هم تموم میشه.

برای متوقف کردن کامل تردپول، متد stop کلاس ThreadPool متد stop همه تردهای داخل تردپول رو صدا میزنه. بعد تردها توی متد stopشون یه فلگ isStopped رو ست میکنن که اون حلقه‌ی داخل Run تموم بشه و بعد متد interrupt خودشون رو صدا میزنن. کاربرد این متد اینه که اگر ترد توی حالت wait برای برداشتن تسک بود (صدا زدن متد dequeue صف باعث میشه ترد بلاک بشه تا تسکی توی صف برای برداشتن پیدا بشه) با یه excetpion از نوع InterruptedException بیخیال انتظار بشه.

نمونه کد:

```java public class ThreadPool { private BlockingQueue taskQueue = null; private List < PoolThread > threads = new ArrayList < PoolThread > (); private boolean isStopped = false; public ThreadPool(int noOfThreads, int maxNoOfTasks) { taskQueue = new BlockingQueue(maxNoOfTasks); for (int i = 0; i < noOfThreads; i++) { threads.add(new PoolThread(taskQueue)); } for (PoolThread thread: threads) { thread.start(); } } public void synchronized execute(Runnable task) { if (this.isStopped) throw new IllegalStateException("ThreadPool is stopped"); this.taskQueue.enqueue(task); } public synchronized void stop() { this.isStopped = true; for (PoolThread thread: threads) { thread.stop(); } } } ``` ```java public class PoolThread extends Thread { private BlockingQueue taskQueue = null; private boolean isStopped = false; public PoolThread(BlockingQueue queue) { taskQueue = queue; } public void run() { while (!isStopped()) { try { Runnable runnable = (Runnable) taskQueue.dequeue(); runnable.run(); } catch (Exception e) { //log or otherwise report exception, //but keep pool thread alive. } } } public synchronized void stop() { isStopped = true; this.interrupt(); //break pool thread out of dequeue() call. } public synchronized void isStopped() { return isStopped; } } ``` * توضیحات و نمونه کد برای سایت Dzone هست.