logo

تجمع موضوع جافا

تجمع جافا الموضوع يمثل مجموعة من مؤشرات الترابط العاملة التي تنتظر المهمة ويتم إعادة استخدامها عدة مرات.

في حالة تجمع مؤشرات الترابط، يتم إنشاء مجموعة من سلاسل الرسائل ذات الحجم الثابت. يتم سحب مؤشر ترابط من تجمع مؤشرات الترابط وتعيين مهمة بواسطة مزود الخدمة. بعد الانتهاء من المهمة، يتم احتواء الخيط في تجمع سلاسل الرسائل مرة أخرى.

طرق تجمع الخيوط

newFixedThreadPool(int s): تقوم الطريقة بإنشاء تجمع مؤشرات ترابط بالحجم الثابت s.

newCachedThreadPool(): تقوم الطريقة بإنشاء تجمع مؤشرات ترابط جديد يقوم بإنشاء سلاسل رسائل جديدة عند الحاجة، ولكنها ستظل تستخدم مؤشر الترابط الذي تم إنشاؤه مسبقًا عندما تكون متاحة للاستخدام.

newSingleThreadExecutor(): تقوم الطريقة بإنشاء موضوع جديد.

الصورة كخلفية في CSS

الاستفادة من تجمع جافا الموضوع

أداء أفضل إنه يوفر الوقت لأنه ليست هناك حاجة لإنشاء موضوع جديد.

الاستخدام في الوقت الحقيقي

يتم استخدامه في Servlet وJSP حيث تقوم الحاوية بإنشاء تجمع مؤشرات ترابط لمعالجة الطلب.

مثال على تجمع خيوط جافا

دعونا نرى مثالاً بسيطًا لتجمع سلاسل رسائل Java باستخدام ExecutorService وExecutors.

خوارزمية لbfs

الملف: WorkerThread.java

 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class WorkerThread implements Runnable { private String message; public WorkerThread(String s){ this.message=s; } public void run() { System.out.println(Thread.currentThread().getName()+' (Start) message = '+message); processmessage();//call processmessage method that sleeps the thread for 2 seconds System.out.println(Thread.currentThread().getName()+' (End)');//prints thread name } private void processmessage() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } 

الملف: TestThreadPool.java

 public class TestThreadPool { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(5);//creating a pool of 5 threads for (int i = 0; i <10; i++) { runnable worker="new" workerthread('' + i); executor.execute(worker); calling execute method of executorservice } executor.shutdown(); while (!executor.isterminated()) system.out.println('finished all threads'); < pre> <p> <strong>Output:</strong> </p> <pre>pool-1-thread-1 (Start) message = 0 pool-1-thread-2 (Start) message = 1 pool-1-thread-3 (Start) message = 2 pool-1-thread-5 (Start) message = 4 pool-1-thread-4 (Start) message = 3 pool-1-thread-2 (End) pool-1-thread-2 (Start) message = 5 pool-1-thread-1 (End) pool-1-thread-1 (Start) message = 6 pool-1-thread-3 (End) pool-1-thread-3 (Start) message = 7 pool-1-thread-4 (End) pool-1-thread-4 (Start) message = 8 pool-1-thread-5 (End) pool-1-thread-5 (Start) message = 9 pool-1-thread-2 (End) pool-1-thread-1 (End) pool-1-thread-4 (End) pool-1-thread-3 (End) pool-1-thread-5 (End) Finished all threads </pre> download this example <h2>Thread Pool Example: 2</h2> <p>Let&apos;s see another example of the thread pool.</p> <p> <strong>FileName:</strong> ThreadPoolExample.java</p> <pre> // important import statements import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.text.SimpleDateFormat; class Tasks implements Runnable { private String taskName; // constructor of the class Tasks public Tasks(String str) { // initializing the field taskName taskName = str; } // Printing the task name and then sleeps for 1 sec // The complete process is getting repeated five times public void run() { try { for (int j = 0; j <= 5; j++) { if (j="=" 0) date dt="new" date(); simpledateformat sdf="new" simpledateformat('hh : mm ss'); prints the initialization time for every task system.out.println('initialization name: '+ taskname + '=" + sdf.format(dt)); } else { Date dt = new Date(); SimpleDateFormat sdf = new SimpleDateFormat(" hh execution system.out.println('time of is complete.'); } catch(interruptedexception ie) ie.printstacktrace(); public class threadpoolexample maximum number threads in thread pool static final int max_th="3;" main method void main(string argvs[]) creating five new tasks runnable rb1="new" tasks('task 1'); rb2="new" 2'); rb3="new" 3'); rb4="new" 4'); rb5="new" 5'); a with size fixed executorservice pl="Executors.newFixedThreadPool(MAX_TH);" passes objects to execute (step 3) pl.execute(rb1); pl.execute(rb2); pl.execute(rb3); pl.execute(rb4); pl.execute(rb5); shutdown pl.shutdown(); < pre> <p> <strong>Output:</strong> </p> <pre> Initialization time for the task name: task 1 = 06 : 13 : 02 Initialization time for the task name: task 2 = 06 : 13 : 02 Initialization time for the task name: task 3 = 06 : 13 : 02 Time of execution for the task name: task 1 = 06 : 13 : 04 Time of execution for the task name: task 2 = 06 : 13 : 04 Time of execution for the task name: task 3 = 06 : 13 : 04 Time of execution for the task name: task 1 = 06 : 13 : 05 Time of execution for the task name: task 2 = 06 : 13 : 05 Time of execution for the task name: task 3 = 06 : 13 : 05 Time of execution for the task name: task 1 = 06 : 13 : 06 Time of execution for the task name: task 2 = 06 : 13 : 06 Time of execution for the task name: task 3 = 06 : 13 : 06 Time of execution for the task name: task 1 = 06 : 13 : 07 Time of execution for the task name: task 2 = 06 : 13 : 07 Time of execution for the task name: task 3 = 06 : 13 : 07 Time of execution for the task name: task 1 = 06 : 13 : 08 Time of execution for the task name: task 2 = 06 : 13 : 08 Time of execution for the task name: task 3 = 06 : 13 : 08 task 2 is complete. Initialization time for the task name: task 4 = 06 : 13 : 09 task 1 is complete. Initialization time for the task name: task 5 = 06 : 13 : 09 task 3 is complete. Time of execution for the task name: task 4 = 06 : 13 : 10 Time of execution for the task name: task 5 = 06 : 13 : 10 Time of execution for the task name: task 4 = 06 : 13 : 11 Time of execution for the task name: task 5 = 06 : 13 : 11 Time of execution for the task name: task 4 = 06 : 13 : 12 Time of execution for the task name: task 5 = 06 : 13 : 12 Time of execution for the task name: task 4 = 06 : 13 : 13 Time of execution for the task name: task 5 = 06 : 13 : 13 Time of execution for the task name: task 4 = 06 : 13 : 14 Time of execution for the task name: task 5 = 06 : 13 : 14 task 4 is complete. task 5 is complete. </pre> <p> <strong>Explanation:</strong> It is evident by looking at the output of the program that tasks 4 and 5 are executed only when the thread has an idle thread. Until then, the extra tasks are put in the queue.</p> <p>The takeaway from the above example is when one wants to execute 50 tasks but is not willing to create 50 threads. In such a case, one can create a pool of 10 threads. Thus, 10 out of 50 tasks are assigned, and the rest are put in the queue. Whenever any thread out of 10 threads becomes idle, it picks up the 11<sup>th </sup>task. The other pending tasks are treated the same way.</p> <h2>Risks involved in Thread Pools</h2> <p>The following are the risk involved in the thread pools.</p> <p> <strong>Deadlock:</strong> It is a known fact that deadlock can come in any program that involves multithreading, and a thread pool introduces another scenario of deadlock. Consider a scenario where all the threads that are executing are waiting for the results from the threads that are blocked and waiting in the queue because of the non-availability of threads for the execution.</p> <p> <strong>Thread Leakage:</strong> Leakage of threads occurs when a thread is being removed from the pool to execute a task but is not returning to it after the completion of the task. For example, when a thread throws the exception and the pool class is not able to catch this exception, then the thread exits and reduces the thread pool size by 1. If the same thing repeats a number of times, then there are fair chances that the pool will become empty, and hence, there are no threads available in the pool for executing other requests.</p> <p> <strong>Resource Thrashing:</strong> A lot of time is wasted in context switching among threads when the size of the thread pool is very large. Whenever there are more threads than the optimal number may cause the starvation problem, and it leads to resource thrashing.</p> <h2>Points to Remember</h2> <p>Do not queue the tasks that are concurrently waiting for the results obtained from the other tasks. It may lead to a deadlock situation, as explained above.</p> <p>Care must be taken whenever threads are used for the operation that is long-lived. It may result in the waiting of thread forever and will finally lead to the leakage of the resource.</p> <p>In the end, the thread pool has to be ended explicitly. If it does not happen, then the program continues to execute, and it never ends. Invoke the shutdown() method on the thread pool to terminate the executor. Note that if someone tries to send another task to the executor after shutdown, it will throw a RejectedExecutionException.</p> <p>One needs to understand the tasks to effectively tune the thread pool. If the given tasks are contrasting, then one should look for pools for executing different varieties of tasks so that one can properly tune them.</p> <p>To reduce the probability of running JVM out of memory, one can control the maximum threads that can run in JVM. The thread pool cannot create new threads after it has reached the maximum limit.</p> <p>A thread pool can use the same used thread if the thread has finished its execution. Thus, the time and resources used for the creation of a new thread are saved.</p> <h2>Tuning the Thread Pool</h2> <p>The accurate size of a thread pool is decided by the number of available processors and the type of tasks the threads have to execute. If a system has the P processors that have only got the computation type processes, then the maximum size of the thread pool of P or P + 1 achieves the maximum efficiency. However, the tasks may have to wait for I/O, and in such a scenario, one has to take into consideration the ratio of the waiting time (W) and the service time (S) for the request; resulting in the maximum size of the pool P * (1 + W / S) for the maximum efficiency.</p> <h2>Conclusion</h2> <p>A thread pool is a very handy tool for organizing applications, especially on the server-side. Concept-wise, a thread pool is very easy to comprehend. However, one may have to look at a lot of issues when dealing with a thread pool. It is because the thread pool comes with some risks involved it (risks are discussed above).</p> <hr></=></pre></10;>
قم بتنزيل هذا المثال

مثال على تجمع الخيوط: 2

دعونا نرى مثالاً آخر على تجمع المواضيع.

جافا لا

اسم الملف: ThreadPoolExample.java

 // important import statements import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.text.SimpleDateFormat; class Tasks implements Runnable { private String taskName; // constructor of the class Tasks public Tasks(String str) { // initializing the field taskName taskName = str; } // Printing the task name and then sleeps for 1 sec // The complete process is getting repeated five times public void run() { try { for (int j = 0; j <= 5; j++) { if (j="=" 0) date dt="new" date(); simpledateformat sdf="new" simpledateformat(\'hh : mm ss\'); prints the initialization time for every task system.out.println(\'initialization name: \'+ taskname + \'=" + sdf.format(dt)); } else { Date dt = new Date(); SimpleDateFormat sdf = new SimpleDateFormat(" hh execution system.out.println(\'time of is complete.\'); } catch(interruptedexception ie) ie.printstacktrace(); public class threadpoolexample maximum number threads in thread pool static final int max_th="3;" main method void main(string argvs[]) creating five new tasks runnable rb1="new" tasks(\'task 1\'); rb2="new" 2\'); rb3="new" 3\'); rb4="new" 4\'); rb5="new" 5\'); a with size fixed executorservice pl="Executors.newFixedThreadPool(MAX_TH);" passes objects to execute (step 3) pl.execute(rb1); pl.execute(rb2); pl.execute(rb3); pl.execute(rb4); pl.execute(rb5); shutdown pl.shutdown(); < pre> <p> <strong>Output:</strong> </p> <pre> Initialization time for the task name: task 1 = 06 : 13 : 02 Initialization time for the task name: task 2 = 06 : 13 : 02 Initialization time for the task name: task 3 = 06 : 13 : 02 Time of execution for the task name: task 1 = 06 : 13 : 04 Time of execution for the task name: task 2 = 06 : 13 : 04 Time of execution for the task name: task 3 = 06 : 13 : 04 Time of execution for the task name: task 1 = 06 : 13 : 05 Time of execution for the task name: task 2 = 06 : 13 : 05 Time of execution for the task name: task 3 = 06 : 13 : 05 Time of execution for the task name: task 1 = 06 : 13 : 06 Time of execution for the task name: task 2 = 06 : 13 : 06 Time of execution for the task name: task 3 = 06 : 13 : 06 Time of execution for the task name: task 1 = 06 : 13 : 07 Time of execution for the task name: task 2 = 06 : 13 : 07 Time of execution for the task name: task 3 = 06 : 13 : 07 Time of execution for the task name: task 1 = 06 : 13 : 08 Time of execution for the task name: task 2 = 06 : 13 : 08 Time of execution for the task name: task 3 = 06 : 13 : 08 task 2 is complete. Initialization time for the task name: task 4 = 06 : 13 : 09 task 1 is complete. Initialization time for the task name: task 5 = 06 : 13 : 09 task 3 is complete. Time of execution for the task name: task 4 = 06 : 13 : 10 Time of execution for the task name: task 5 = 06 : 13 : 10 Time of execution for the task name: task 4 = 06 : 13 : 11 Time of execution for the task name: task 5 = 06 : 13 : 11 Time of execution for the task name: task 4 = 06 : 13 : 12 Time of execution for the task name: task 5 = 06 : 13 : 12 Time of execution for the task name: task 4 = 06 : 13 : 13 Time of execution for the task name: task 5 = 06 : 13 : 13 Time of execution for the task name: task 4 = 06 : 13 : 14 Time of execution for the task name: task 5 = 06 : 13 : 14 task 4 is complete. task 5 is complete. </pre> <p> <strong>Explanation:</strong> It is evident by looking at the output of the program that tasks 4 and 5 are executed only when the thread has an idle thread. Until then, the extra tasks are put in the queue.</p> <p>The takeaway from the above example is when one wants to execute 50 tasks but is not willing to create 50 threads. In such a case, one can create a pool of 10 threads. Thus, 10 out of 50 tasks are assigned, and the rest are put in the queue. Whenever any thread out of 10 threads becomes idle, it picks up the 11<sup>th </sup>task. The other pending tasks are treated the same way.</p> <h2>Risks involved in Thread Pools</h2> <p>The following are the risk involved in the thread pools.</p> <p> <strong>Deadlock:</strong> It is a known fact that deadlock can come in any program that involves multithreading, and a thread pool introduces another scenario of deadlock. Consider a scenario where all the threads that are executing are waiting for the results from the threads that are blocked and waiting in the queue because of the non-availability of threads for the execution.</p> <p> <strong>Thread Leakage:</strong> Leakage of threads occurs when a thread is being removed from the pool to execute a task but is not returning to it after the completion of the task. For example, when a thread throws the exception and the pool class is not able to catch this exception, then the thread exits and reduces the thread pool size by 1. If the same thing repeats a number of times, then there are fair chances that the pool will become empty, and hence, there are no threads available in the pool for executing other requests.</p> <p> <strong>Resource Thrashing:</strong> A lot of time is wasted in context switching among threads when the size of the thread pool is very large. Whenever there are more threads than the optimal number may cause the starvation problem, and it leads to resource thrashing.</p> <h2>Points to Remember</h2> <p>Do not queue the tasks that are concurrently waiting for the results obtained from the other tasks. It may lead to a deadlock situation, as explained above.</p> <p>Care must be taken whenever threads are used for the operation that is long-lived. It may result in the waiting of thread forever and will finally lead to the leakage of the resource.</p> <p>In the end, the thread pool has to be ended explicitly. If it does not happen, then the program continues to execute, and it never ends. Invoke the shutdown() method on the thread pool to terminate the executor. Note that if someone tries to send another task to the executor after shutdown, it will throw a RejectedExecutionException.</p> <p>One needs to understand the tasks to effectively tune the thread pool. If the given tasks are contrasting, then one should look for pools for executing different varieties of tasks so that one can properly tune them.</p> <p>To reduce the probability of running JVM out of memory, one can control the maximum threads that can run in JVM. The thread pool cannot create new threads after it has reached the maximum limit.</p> <p>A thread pool can use the same used thread if the thread has finished its execution. Thus, the time and resources used for the creation of a new thread are saved.</p> <h2>Tuning the Thread Pool</h2> <p>The accurate size of a thread pool is decided by the number of available processors and the type of tasks the threads have to execute. If a system has the P processors that have only got the computation type processes, then the maximum size of the thread pool of P or P + 1 achieves the maximum efficiency. However, the tasks may have to wait for I/O, and in such a scenario, one has to take into consideration the ratio of the waiting time (W) and the service time (S) for the request; resulting in the maximum size of the pool P * (1 + W / S) for the maximum efficiency.</p> <h2>Conclusion</h2> <p>A thread pool is a very handy tool for organizing applications, especially on the server-side. Concept-wise, a thread pool is very easy to comprehend. However, one may have to look at a lot of issues when dealing with a thread pool. It is because the thread pool comes with some risks involved it (risks are discussed above).</p> <hr></=>

توضيح: يتضح من خلال النظر إلى مخرجات البرنامج أن المهمتين 4 و5 يتم تنفيذهما فقط عندما يكون الخيط خاملاً. وحتى ذلك الحين، يتم وضع المهام الإضافية في قائمة الانتظار.

الوجبات الجاهزة من المثال أعلاه هي عندما يريد المرء تنفيذ 50 مهمة ولكن ليس على استعداد لإنشاء 50 سلسلة رسائل. في مثل هذه الحالة، يمكن للمرء إنشاء مجموعة من 10 سلاسل رسائل. وبالتالي، يتم تعيين 10 مهام من أصل 50، ويتم وضع الباقي في قائمة الانتظار. عندما يصبح أي خيط من بين 10 خيوط خاملاً، فإنه يلتقط الـ 11ذمهمة. ويتم التعامل مع المهام المعلقة الأخرى بنفس الطريقة.

المخاطر التي تنطوي عليها تجمعات الموضوع

فيما يلي المخاطر المتضمنة في تجمعات مؤشرات الترابط.

طريق مسدود: من المعروف أن حالة توقف تام يمكن أن تحدث في أي برنامج يتضمن تعدد مؤشرات الترابط، ويقدم تجمع مؤشرات الترابط سيناريو آخر لحالة توقف تام. خذ بعين الاعتبار سيناريو حيث تنتظر كافة سلاسل الرسائل التي يتم تنفيذها نتائج من سلاسل الرسائل المحظورة وتنتظر في قائمة الانتظار بسبب عدم توفر سلاسل الرسائل للتنفيذ.

تسرب الموضوع: يحدث تسرب مؤشرات الترابط عندما تتم إزالة مؤشر ترابط من التجمع لتنفيذ مهمة ولكنه لا يعود إليه بعد اكتمال المهمة. على سبيل المثال، عندما يطرح مؤشر ترابط الاستثناء ولا تتمكن فئة التجمع من التقاط هذا الاستثناء، فسيخرج مؤشر الترابط ويقلل حجم تجمع مؤشر الترابط بمقدار 1. إذا تكرر نفس الشيء عدة مرات، فهناك فرص عادلة لذلك سيصبح المجمع فارغًا، وبالتالي لا توجد سلاسل رسائل متاحة في المجمع لتنفيذ الطلبات الأخرى.

سحق الموارد: يتم إهدار الكثير من الوقت في تبديل السياق بين سلاسل الرسائل عندما يكون حجم تجمع مؤشرات الترابط كبيرًا جدًا. كلما زاد عدد المواضيع عن العدد الأمثل قد يسبب مشكلة المجاعة، ويؤدي إلى تحطيم الموارد.

نقطة لنتذكر

لا تضع المهام التي تنتظر بشكل متزامن النتائج التي تم الحصول عليها من المهام الأخرى في قائمة الانتظار. وقد يؤدي ذلك إلى حالة من الجمود، كما هو موضح أعلاه.

يجب توخي الحذر عند استخدام الخيوط للعملية طويلة الأمد. قد يؤدي ذلك إلى انتظار الخيط إلى الأبد وسيؤدي في النهاية إلى تسرب المورد.

يونكس إنشاء الدليل

في النهاية، يجب إنهاء تجمع الخيوط بشكل صريح. إذا لم يحدث ذلك، فسيستمر البرنامج في التنفيذ ولن ينتهي أبدًا. قم باستدعاء طريقة إيقاف التشغيل () في تجمع مؤشرات الترابط لإنهاء المنفذ. لاحظ أنه إذا حاول شخص ما إرسال مهمة أخرى إلى المنفذ بعد إيقاف التشغيل، فسيطرح استثناء RejectedExecutionException.

يحتاج المرء إلى فهم المهام لضبط تجمع مؤشرات الترابط بشكل فعال. إذا كانت المهام المحددة متناقضة، فيجب على المرء أن يبحث عن مجموعات لتنفيذ أنواع مختلفة من المهام حتى يتمكن من ضبطها بشكل صحيح.

مؤشر الرجوع ج

لتقليل احتمالية تشغيل JVM خارج الذاكرة، يمكن للمرء التحكم في الحد الأقصى من سلاسل العمليات التي يمكن تشغيلها في JVM. لا يمكن لتجمع سلاسل الرسائل إنشاء سلاسل رسائل جديدة بعد وصوله إلى الحد الأقصى.

يمكن لتجمع مؤشرات الترابط استخدام نفس مؤشر الترابط المستخدم إذا انتهى مؤشر الترابط من تنفيذه. وبالتالي، يتم توفير الوقت والموارد المستخدمة لإنشاء موضوع جديد.

ضبط تجمع الموضوع

يتم تحديد الحجم الدقيق لتجمع مؤشرات الترابط من خلال عدد المعالجات المتاحة ونوع المهام التي يتعين على مؤشرات الترابط تنفيذها. إذا كان النظام يحتوي على معالجات P التي حصلت فقط على عمليات من النوع الحسابي، فإن الحد الأقصى لحجم تجمع الخيوط P أو P + 1 يحقق أقصى قدر من الكفاءة. ومع ذلك، قد يتعين على المهام انتظار الإدخال/الإخراج، وفي مثل هذا السيناريو، يتعين على المرء أن يأخذ في الاعتبار نسبة وقت الانتظار (W) ووقت الخدمة (S) للطلب؛ مما يؤدي إلى الحد الأقصى لحجم المسبح P * (1 + W / S) للحصول على أقصى قدر من الكفاءة.

خاتمة

يعد تجمع مؤشرات الترابط أداة مفيدة جدًا لتنظيم التطبيقات، خاصة على جانب الخادم. من حيث المفهوم، من السهل جدًا فهم تجمع الخيوط. ومع ذلك، قد يتعين على المرء أن ينظر إلى الكثير من المشكلات عند التعامل مع تجمع مؤشرات الترابط. ذلك لأن تجمع مؤشرات الترابط يأتي مع بعض المخاطر التي ينطوي عليها (تمت مناقشة المخاطر أعلاه).