تكلفة بدء تشغيل مؤشر ترابط في النظام مرتفعة نسبيًا لأنه يتضمن تفاعلًا مع نظام التشغيل. ميزة استخدام تجمع الخيوط هي تحسين الأداء. عندما يحتوي النظام على عدد كبير من الخيوط المتزامنة ، فإنه سيؤدي إلى انخفاض حاد في أداء النظام وحتى يتسبب في تعطل JVM. يمكن أن يتحكم الحد الأقصى لعدد مؤشرات الترابط في معلمة تجمع مؤشرات الترابط في عدد مؤشرات الترابط المتزامنة في النظام حتى لا تتجاوز عدد المرات.
1. يتم استخدام فئة مصنع المنفذين لإنشاء تجمع مؤشرات ترابط . تحتوي فئة المصنع هذه على طرق المصنع الثابتة التالية لإنشاء تجمع مؤشرات الترابط المقابل. تجمع مؤشرات الترابط الذي تم إنشاؤه هو كائن من ExecutorSorservice. طريقة إرسال الكائن أو طريقة تنفيذها لتنفيذ المهام القابلة للتشغيل أو القابلة للاتصال المقابلة. يستدعي تجمع الخيوط نفسه طريقة إيقاف التشغيل () لإيقاف تجمع الخيوط عندما لم يعد هناك حاجة إليه. بعد استدعاء الطريقة ، لن يسمح تجمع الخيوط بإضافة المهام ، ولكن لن تموت حتى يتم تنفيذ جميع المهام المضافة.
1. NewCachedThreadPool () ينشئ تجمع مؤشرات ترابط مع وظيفة التخزين المؤقت ويقدم مؤشر الترابط الذي تم إنشاؤه بواسطة المهمة (كائن Runnable أو Collable) من تجمع مؤشر الترابط. إذا تم الانتهاء من التنفيذ ، فسيتم تخزينه مؤقتًا في المخزونات المخزالية لاستخدام المهام التي تحتاج إلى تنفيذها لاحقًا.
استيراد java.util.concurrent.executorservice ؛ استيراد java.util.concurrent.executors ؛ الطبقة العامة cachethreadpool {static class task reghenable { @ @adoverride run () thread.currentThRead (). getAllStackTraces (). size ()) ؛ }} public static void main (string [] args) {executorService cachethreadpool = evelysors.newcachedthreadpool () ؛ // أضف ثلاث مهام إلى تجمع مؤشرات الترابط أولاً لـ (int i = 0 ؛ i <3 ؛ i ++) {cachethreadpool.execute (مهمة جديدة ()) ؛ } // بعد تنفيذ مؤشرات الترابط الثلاثة ، أضف ثلاث مهام إلى مجموعة مؤشرات الترابط مرة أخرى ، حاول {thread.sleep (3000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } لـ (int i = 0 ؛ i <3 ؛ i ++) {cachethreadpool.execute (new task ()) ؛ }}}نتائج التنفيذ هي كما يلي:
cachethreadpool $ task@2d312eb9 pool-1-thread-1 allstacktraces الحجم: 7CachethReadpool $ task@59522b86 pool-1-thread-3 allstacktraces map: 7cachreadpool $ task@73db89f pool-1-thread-all allstacktraces map: pool-1-thread-3 allstacktraces حجم الخريطة: 7CachethReadPool $ task@256d5600 pool-1-thread-1 allstacktraces حجم الخريطة: 7 cachethreadpool $ task@7d1c5894 pool-1-thread-2 allstacktraces حجم الخريطة: 7.
يتم تخزين كائنات مؤشر الترابط في تجمع مؤشرات الترابط وإعادة استخدامها عند تنفيذ مهام جديدة. ومع ذلك ، إذا كان هناك الكثير من التزامن ، فسيظل تجمع مؤشرات ترابط ذاكرة التخزين المؤقت ينشئ العديد من كائنات مؤشرات الترابط.
2. NewfixedThreadPool (int nthreads) ينشئ تجمع مؤشرات ترابط مع عدد محدد من مؤشرات الترابط التي يمكن إعادة استخدامها بواسطة مؤشرات الترابط.
استيراد java.util.concurrent.executorservice ؛ استيراد java.util.concurrent.executors ؛ الطبقة العامة الثابتة {static class task state runnable { @ @public run () thread.currentThRead (). getAllStackTraces (). size ()) ؛ }} public static void main (string [] args) {executorService flexThreadPool = Executors.NewFixedThreadPool (3) ؛ // أضف أولاً ثلاث مهام إلى تجمع مؤشرات الترابط لـ (int i = 0 ؛ i <5 ؛ i ++) {fixedthreadpool.execute (new Task ()) ؛ } // بعد تنفيذ مؤشرات الترابط الثلاثة ، أضف ثلاث مهام إلى مجموعة مؤشرات الترابط مرة أخرى ، حاول {thread.sleep (3) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } لـ (int i = 0 ؛ i <3 ؛ i ++) {flexThreadPool.execute (New Task ()) ؛ }}}نتائج التنفيذ:
FlexThreadPool $ task@7045c12d pool-1-thread-2 allstacktraces حجم الخريطة: 7fixedThreadPool $ task@50fa0bef pool-1-thread-2 allstacktraces size: 7fixedThreadPool $ task@ccb1870 pool-thread-2 allstacktractes size: AllStackTraces MAP SIZE: 7FIXEDTHREADPOOL $ TASK@5BDEFF18 POUN-1-THEREAD-2 AllStackTraces حجم الخريطة: 7FixedTherTheReadPool $ task@7d5554e1 pool-1-thread-1 allstacktraces size: 7fixedThreadPool $ task@24468092 pool-1-thread-3 allstacktraces map map map: 7fixedThreadPool $ task@fa7b978 pool-1-thread-2 allstacktraces حجم الخريطة: 7
3. NewsingleThreadExecutor () ، قم بإنشاء تجمع مؤشرات ترابط مع مؤشرات ترابط واحدة فقط ، وهو ما يعادل استدعاء NewFixedThreadPool (1)
4. NewSheDuleDthravePool (int corepoolsize) ، ينشئ تجمع مؤشرات ترابط مع عدد محدد من مؤشرات الترابط ، والتي يمكن تنفيذ مؤشرات الترابط بعد تأخير محدد. يمكنك أيضًا تكرار موضوع في فترة زمنية معينة ، مع العلم أنه يمكنك استدعاء إيقاف التشغيل () لإغلاق تجمع الخيوط.
الأمثلة على النحو التالي:
استيراد java.util.concurrent.executors ؛ استيراد java.util.concurrent.scheduleDexecutorService ؛ استيراد java.util.concurrent.timeunit ؛ الطبقة العامة screadThreadPool {static class charce reghable {override run () + "" + thread.currentThRead (). getName () + "allstacktraces حجم الخريطة:" + thread.currentThRead (). getAllStackTraces (). size ()) ؛ }} public static void main (string [] args) {scrededExecutorService ScheduledExecutorService = Executors.NewScheduledThreadPool (3) ؛ SchedeDexecutorService.schedule (مهمة جديدة () ، 3 ، TimeUnit.Seconds) ؛ ScripedExecutorService.ScheduleAtfixedrate (مهمة جديدة () ، 3 ، 5 ، timeUnit.Seconds) ؛ حاول {thread.sleep (30 * 1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } schedulexecutorservice.shutdown () ؛ }}نتائج التشغيل كما يلي:
Time 1458921795240 Pool-1-Thread-1 AllstackTraces حجم: 6 Time 1458921795241 Pool-1-Thread-2 AllstackTraces Size: 6 Time 1458921800240 Pool-1-Horead-1 Allstacktraces Size: 7 Time 1458921805240 Pool-------1TheD-1 alstacktraces Mapp-1 1458921810240 POOW-1-THREAD-1 AllStackTraces حجم الخريطة: 7 الوقت 1458921815240 POOL-1-THREAD-1 Allstacktraces حجم الخريطة: 7 الوقت 1458921820240 POOW-1-THREAD-1 ALLSTACKTRACES SIZE: 7 SIZE: 7
كما يتضح من وقت التشغيل ، يتم تنفيذ المهمة في دورة مدتها 5 ثوان.
5. NewsingleThreadScheduleDexecutor () ينشئ مجموعة خيوط مع موضوع واحد فقط ، ويستدعي NewsChedThedThreadPool (1).
2. forkjoinpool و forkjointask
Forkjoinpool هو فئة تنفيذ من ExecutorService. وهو يدعم تقسيم المهمة إلى مهام صغيرة متعددة في الحوسبة المتوازية ، ويجمع نتائج حساب المهام الصغيرة المتعددة في نتائج الحساب الكلية. لديها اثنين من المُنشرين
Forkjoinpool (int paralitism) يخلق forkjoinpool الذي يحتوي على مؤشرات ترابط التوازي.
ForkJoinPool () ، ينشئ ForkJoinPool باستخدام قيمة إرجاع وقت التشغيل.
يمثل ForkJointask مهمة يمكن أن تكون موازية ودمج. إنها فئة مجردة تنفذ واجهة <T> المستقبل. يحتوي على فئتين فرعيتين مجردة ، تمثل إعادة تكرار المهمة دون قيمة إرجاع ومقالفة Recursivetask ذات قيمة الإرجاع. يمكنك أن ترث هاتين الفئتين التجريدين وفقًا لاحتياجات محددة لتنفيذ الكائنات الخاصة بك ، ثم استدعاء طريقة إرسال ForkJoinPool للتنفيذ.
مثال RecuriveAction هو كما يلي ، وتنفيذ مخرجات متوازية من 0-300 أرقام.
استيراد java.util.concurrent.forkjoinpool ؛ استيراد java.util.concurrent.recursiveact ؛ بداية int الخاصة ؛ نهاية int الخاصة Public PrintTask (int start ، int end) {this.start = start ؛ this.end = نهاية ؛ } override void compute () {if (end - start <threshold) {for (int i = start ؛ i <end ؛ i ++) {system.out.println (thread.currentThread (). getName () + " + i) ؛ }} آخر {int middle = (start + end) / 2 ؛ printtask left = new printtask (start ، middle) ؛ printtask right = new printtask (middle ، end) ؛ left.fork () ؛ right.fork () ؛ }}} main public static void (string [] args) {forkjoinpool pool = new forkjoinpool () ؛ pool.submit (New PrintTask (0 ، 300)) ؛ حاول {pool.awaittermination (2 ، timeUnit.Seconds) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } pool.shutdown () ؛ }}بعد تقسيم المهمة الصغيرة ، اتصل بالطريقة الشوكة () للمهمة وأضفها إلى forkjoinpool للتنفيذ بالتوازي.
مثال Recursivetask ، ينفذ حساب موازي من 100 أعداد صحيحة إلى SUM. تقسم إلى كل 20 رقمًا وتلخيصها للحصول على النتيجة ، ودمجها في النتيجة النهائية في النهاية.
استيراد java.util.random ؛ استيراد java.util.concurrent.executionException ؛ استيراد java.util.concurrent.forkjoinpool ؛ استيراد java.util.concurrent.future ؛ recursaStask recursaStask <upergaint عتبة int النهائية الثابتة الخاصة = 20 ؛ private int arr [] ؛ بداية int الخاصة ؛ نهاية int الخاصة caltask العامة (int [] arr ، int start ، int end) {this.arr = arr ؛ this.start = start ؛ this.end = نهاية ؛ } Override integer compute () {int sum = 0 ؛ if (end - start <عتبة) {for (int i = start ؛ i <end ؛ i ++) {sum+= arr [i] ؛ } system.out.println (thread.currentThRead (). getName () + "sum:" + sum) ؛ إرجاع مجموع } آخر {int middle = (start + end) / 2 ؛ Caltask left = caltask new (arr ، start ، middle) ؛ Caltask Right = New Caltask (ARR ، Middle ، End) ؛ left.fork () ؛ right.fork () ؛ العودة إلى اليسار. join () + right.join () ؛ }}} main static void static (string [] args) {int arr [] = new int [100] ؛ عشوائي عشوائي = جديد عشوائي () ؛ int total = 0 ؛ لـ (int i = 0 ؛ i <arr.length ؛ i ++) {int tmp = random.nextint (20) ؛ TOTAL += (ARR [I] = TMP) ؛ } system.out.println ("total" + total) ؛ Forkjoinpool Pool = New Forkjoinpool (4) ؛ المستقبل <integer> المستقبل = pool.submit (caltask جديد (arr ، 0 ، arr.length)) ؛ حاول {system.out.println ("cal result:" + future.get ()) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } catch (executionException) e) {e.printStackTrace () ؛ } pool.shutdown () ؛ }}نتائج التنفيذ هي كما يلي:
إجمالي 912ForkjoInpool-1-Worker-2 المبلغ: 82ForkJoInpool-1-Worker-2 المبلغ: 123ForkjoInpool-1-Worker-2: 144forkjoinpool-1-Worker-3 Sum: 128ForkObool-1-Worker-2 Sum: 106forkjoinpool-1-Gworker-2: المبلغ: 121ForkJoInpool-1-Work-3 Sum: 89Cal النتيجة: 912
بعد تنفيذ المهام الفرعية ، اتصل بطريقة Join () للمهمة للحصول على نتيجة تنفيذ المهام الفرعية ، ثم إضافتها للحصول على النتيجة النهائية.