ورود

View Full Version : راهنمایی برای Custom Threadpool



MSHService
دوشنبه 22 دی 1393, 16:24 عصر
با درود و ادب
دوستان من میخوام ترد هام رو بتونه دوباره استفاده کنم و کیلشون نکنم و دوباره درستشون نکنم. نمیخوامم از ترد پول استفاده کنم.
میخوام بتونم خودم تردهام رو مدیریت کنم.
چطور میتونم این کارر و انجام بدم؟!

ahmad.mo74
سه شنبه 23 دی 1393, 22:23 عصر
سلام

من این سوالو چند ساعت پیش دیدم، خیلیم روش فکر کردم. آخر به این نتیجه رسیدم که بهترین Thread Pool ای که میشه نوشت همونیه که تو خود jdk هست (کلا پکیج java.util.concurrent به خصوص کلاس های ThreadPool و ExecutorService و ForkJoinPool) ، فکر نکنم حتی یک نفر هم جرات بکنه و بگه من بهتر از اونارو میتونم بنویسم. نوشتن دوباره یه Thread Pool وقعا مثل چرخوندن لقمه دور دهن میمونه. به خصوص اینکه مدیریت ترد ها کار اصلا ساده ای نیست و از دست من و شما برنمیاد...

اما مدیریت تسک ها و کنترل هر چه بیشتر روی اونارو میتونیم خودمون انجام بدیم. من یه مثال تقریبا کامل نوشتم که البته توش از همون کلاس های پکیج java.util.concurrent استفاده کردم، اما فکر میکنم دیگه تقریبا هر نوع کنترلی که روی تسک هات بخوای انجام بدی رو با این api به راحتی بتونی انجام بدی.

چون سورسش زیاد شد فقط لینک دانلودشو گذاشتم.


ConcurrentTaskService (http://bit.ly/1y8njLP)

ahmad.mo74
چهارشنبه 24 دی 1393, 18:18 عصر
این نکته رو هم بگم که چند نوع پیاده سازی برای ExecutorService هست که مهم هاش ایناس :

1- Single Thread Executor :


ExecutorService service = Executors.newSingleThreadExecutor();


در این حالت یک Thread Pool که فقط یک ترد توش داره ساخته میشه و هر تسکی بهش داده بشه فقط روی یک ترد اجرا میشه و در صورتی که ترد در حال اجرای تسکی باشه، تسک های بعدی ای که بهش بدی پشت سر هم و بعد از اتمام تسک قبلی اجرا میشه.
تو این روش ترد جدید ساخته نمیشه و از همون قبلی استفاده میشه و اگر به هر دلیلی اون ترد interrupt شد، یک ترد جدید جایگزینش میشه.

2- Fixed Thread Pool :


ExecutorService service = Executors.newFixedThreadPool(10);


تو این حالت یه ترد پول با تعداد مشخصی از ترد (مثلا 10 تا) ساخته میشه. فرقش با Single Thread Executor تو اینه که به جای یک ترد n ترد داریم و همزمان میتونیم n تسک رو انجام بدیم و اگر تسک جدیدی اضافه بشه و همه ترد ها در حال اجرا باشن، تسکهای جدید به ترتیب منتظر میمونن تا تردی آزاد بشه و بعد اجرا میشن.
تو این روش هم در صورتی ترد جدید ساخته میشه که به هر دلیلی یک یا چند ترد interrupt بشن.

3- Cached Thread Pool :


ExecutorService service = Executors.newCachedThreadPool();


در این حالت یک Thread Pool ای که هیچ تردی توش نیست ساخته میشه. هر زمان که نیاز باشه ترد جدید ساخته میشه، تسک اجرا میشه و دوباره به pool برگردونده میشه. اگر هم توی pool ترد آزاد داشته باشیم از همون استفاده میشه و ترد جدید ساخته نمیشه. در صورتی که از تردی به مدت 60 ثانیه استفاده نشه اون ترد از توی pool حذف میشه تا resource آزاد بشه. تعداد ترد ها از 0 تا Integer.MAX_VALUE متغیره.

Work Stealing Pool :

در این حالت از کلاس ForkJoinPool برای اجرای تسک ها استفاده میشه و این قابلیت رو داره که همزمان از تمام هسته ها استفاده کنه. تسک ها به صورت Asynchronous اجرا میشن یعنی برای اجرای تسک ها از یک Queue یا first-in first-out استفاده میشه. اما اگر میخواید به تسک ها صورت Stack یا last-in first-out اجرا بشن باید این کارو بکنید :


ExecutorService service = new ForkJoinPool(Runtime.getRuntime().availableProcess ors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, false);


Scheduled Thread Pool :


ScheduledExecutorService service = Executors.newScheduledThreadPool(10);


در این حالت یک ScheduledExecutorService داریم با n ترد (مثل Fixed Thread Pool) با این تفاوت که میتونیم تسک هارو زمان بندی کنیم تا مثلا بعد از یه وقفه ای یا به صورت دوره ای اجرا بشن.