1. บทนำ
การใช้พูลแบบด้ายอย่างมีเหตุผลสามารถนำประโยชน์สามประการ ครั้งแรก: ลดการใช้ทรัพยากร ลดการบริโภคที่เกิดจากการสร้างเธรดและการทำลายโดยการนำเธรดที่สร้างขึ้นมาใหม่ ประการที่สอง: ปรับปรุงความเร็วในการตอบสนอง เมื่องานมาถึงงานสามารถดำเนินการได้ทันทีหลังจากสร้างเธรด ประการที่สาม: ปรับปรุงการจัดการด้าย หัวข้อเป็นทรัพยากรที่หายาก หากสร้างขึ้นอย่างไม่ จำกัด พวกเขาจะไม่เพียง แต่ใช้ทรัพยากรระบบ แต่ยังลดความเสถียรของระบบ การใช้พูลเธรดสามารถรวมการจัดสรรการปรับแต่งและการตรวจสอบแบบรวม อย่างไรก็ตามในการใช้เหตุผลอย่างมีเหตุผลของพูลเธรดคุณต้องรู้หลักการของมันเป็นอย่างดี
2. การใช้พูลเธรด
เธรดสี่ประเภทที่จัดทำโดยผู้ดำเนินการ 1. NewcachedThreadPool สร้างพูลเธรดที่สามารถแคชได้ หากความยาวของพูลเธรดเกินความต้องการการประมวลผลจะสามารถรีไซเคิลเธรดที่ไม่ได้ใช้งานได้อย่างยืดหยุ่น หากไม่มีการรีไซเคิลให้สร้างเธรดใหม่ 2. NewFixedThreadPool สร้างพูลเธรดที่มีความยาวคงที่ซึ่งสามารถควบคุมจำนวนเกลียวที่เกิดขึ้นพร้อมกันได้สูงสุดและเธรดส่วนเกินจะรออยู่ในคิว 3.NEWSCHEDULEDTHREADPOOL สร้างพูลเธรดที่มีความยาวคงที่ซึ่งรองรับการดำเนินงานตามเวลาและเป็นระยะ 4. NewSingLetHreadExecutor สร้างพูลเธรดเดียวซึ่งจะใช้เธรดคนงานที่ไม่ซ้ำกันเพื่อดำเนินการงานเพื่อให้มั่นใจว่างานทั้งหมดจะถูกดำเนินการตามลำดับที่ระบุ (FIFO, LIFO, ลำดับความสำคัญ)
1. NewcachedthreadPool สร้างพูลเธรดที่แคช หากความยาวของพูลเธรดเกินความต้องการการประมวลผลจะสามารถรีไซเคิลเธรดที่ไม่ได้ใช้งานได้อย่างยืดหยุ่น หากไม่มีการรีไซเคิลให้สร้างเธรดใหม่ ตัวอย่างมีดังนี้
ExecutorService ExecutorService = Executors.newCachedThreadPool (); สำหรับ (int i = 0; i <5; i ++) {ดัชนี int สุดท้าย = i; ลอง {thread.sleep (ดัชนี * 1000); } catch (interruptedException e) {e.printStackTrace (); } ExecutorService.Execute (ใหม่ runnable () {@Override public void run () {system.out.println (thread.currentthread (). getName () + "," + ดัชนี);}});} // ข้อมูลคอนโซล Pool-1-Thread-1,0pool-1-Thread-1,1pool-1-Thread-1,2pool-1-Thread-1,3pool-1-Thread-1,42. NewFixedThreadPool สร้างพูลเธรดที่มีความยาวคงที่ซึ่งสามารถควบคุมจำนวนเกลียวที่เกิดขึ้นพร้อมกันได้สูงสุดและเธรดส่วนเกินจะรออยู่ในคิว ตัวอย่างมีดังนี้
ExecutORSERVICE recidEthReadPool = executors.newFixedThreadPool (4); สำหรับ (int i = 0; i <5; i ++) {ดัชนี int สุดท้าย = i; recidethreadpool.execute (ใหม่ runnable () {@override public void run () {ลอง {system.out.println (thread.currentthread (). getName () + "," + ดัชนี); thread.sleep (2000); Pool-1-Thread-1,0pool-1-Thread-2,1Pool-1-Thread-3,2pool-1-Thread-4,3pool-1-Thread-1,43.NEWSCHEDULEDTHREADPOOL สร้างพูลเธรดที่มีความยาวคงที่และตัวอย่างของวัฏจักรการสนับสนุนและงานเวลามีดังนี้
ScheduleDexecutorService ScheduleDTHreadPool = Executors.newscheduledThreadPool (5); System.out.println ("ก่อน:" + System.currentTimeMillis ()/1000); scheduledThreadpool.schedule (ใหม่ runnable () {@Override public void run () {system.out.println ("การดำเนินการล่าช้าเป็นเวลา 3 วินาที:" + system.currenttimemillis ()/1000);}}, 3, timeunit.seconds); +System.currentTimemillis ()/1000); // ข้อมูลคอนโซลก่อน: 1518012703 หลังจาก: 1518012703 ล่าช้าเป็นเวลา 3 วินาที: 1518012706System.out.println ("ก่อน:" +system.currenttimeMillis ()/1000); {@Override โมฆะสาธารณะ Run () {System.out.println ("หลังจากความล่าช้า 1 วินาทีดำเนินการหนึ่งครั้งใน 3 วินาที:" +System.currentTimeMillis ()/1000);ข้อความคอนโซล
ก่อน: 1518013024
หลัง: 1518013024
หลังจากการหน่วงเวลา 1 วินาทีดำเนินการหนึ่งครั้งใน 3 วินาที: 1518013025
หลังจากการหน่วงเวลา 1 วินาทีดำเนินการหนึ่งครั้งใน 3 วินาที: 1518013028
หลังจากการหน่วงเวลา 1 วินาทีดำเนินการหนึ่งครั้งใน 3 วินาที: 1518013031
4. NewSingLetHreadExecutor สร้างพูลเธรดเดียวซึ่งใช้เฉพาะเธรดของคนงานเพื่อดำเนินการงานเพื่อให้มั่นใจในการสั่งซื้อ ตัวอย่างมีดังนี้
ExecutorService SingLetHreatHreadExecutor = Executors.newsingLetHreathedExecutor (); สำหรับ (int i = 0; i <10; i ++) {ดัชนี int สุดท้าย = i; singlethreathexecutor.execute (ใหม่ runnable () {@Override public void run () {ลอง {system.out.println (thread.currentthread (). getName () + "," + ดัชนี); thread.sleep (2000);ข้อมูลคอนโซล
pool-1-Thread-1,0
Pool-1-Thread-1,1
Pool-1-Thread-1,2
Pool-1-Thread-1,3
Pool-1-Thread-1,4
ส่งงานไปยังพูลเธรด ความแตกต่างระหว่าง Execute () และ subment () ในคลาส ThreadPoolexecutor เป็นวิธีที่ประกาศในผู้ดำเนินการ มันถูกนำไปใช้ใน Threadpoolexecutor วิธีนี้เป็นวิธีการหลักของ Threadpoolexecutor ด้วยวิธีนี้สามารถส่งงานไปยังพูลเธรดและส่งไปยังพูลเธรดเพื่อดำเนินการ
วิธีการส่ง () เป็นวิธีที่ประกาศใน ExecutorService มันถูกนำไปใช้ใน AbstractExecutorservice มันไม่ได้เขียนใหม่ใน threadpoolexecutor วิธีนี้ยังใช้ในการส่งงานไปยังพูลเธรด อย่างไรก็ตามมันแตกต่างจากวิธีการดำเนินการ () มันสามารถส่งคืนผลลัพธ์ของการดำเนินการงาน ตรวจสอบการใช้วิธีการส่ง () ผ่านซอร์สโค้ดและคุณจะพบว่าจริง ๆ แล้วมันเป็นวิธีการที่เรียกใช้ () ที่เรียกว่า แต่ใช้อนาคตเพื่อรับผลการดำเนินการของงาน
/** * @throws ปฏิเสธ ExecutionException {@inheritdoc} * @throws nullpointerexception {@inheritdoc} */อนาคตสาธารณะ <?> ส่ง RunnableFuture <Void> ftask = newTaskfor (งาน, null); ดำเนินการ (ftask); ส่งคืน ftask;}ปิดพูลเธรดเราสามารถปิดพูลเธรดได้โดยเรียกใช้วิธีการปิดหรือปิดการใช้งานของพูลเธรด แต่หลักการการนำไปใช้งานแตกต่างกัน หลักการของการปิดตัวลงคือการตั้งค่าสถานะของพูลเธรดเป็นสถานะการปิดตัวและจากนั้นขัดจังหวะเธรดทั้งหมดที่ไม่ได้ทำงาน หลักการของการปิดตัวลงคือการสำรวจเธรดคนงานในพูลเธรดจากนั้นเรียกใช้วิธีการขัดจังหวะของเธรดทีละหนึ่งเพื่อขัดจังหวะเธรดดังนั้นงานที่ไม่สามารถตอบสนองต่อการขัดจังหวะอาจไม่ถูกยกเลิก SHUTDENDNOWNOW จะตั้งค่าสถานะของพูลเธรดให้หยุดก่อนจากนั้นลองหยุดกระทู้ทั้งหมดที่กำลังดำเนินการหรือหยุดงานและกลับไปที่รายการรองานที่จะดำเนินการ
ตราบใดที่หนึ่งในสองวิธีการปิดนี้เรียกว่าวิธีการ ISShutdown จะกลับมาเป็นจริง เมื่องานทั้งหมดถูกปิดหมายความว่าสระว่ายน้ำจะปิดสำเร็จ การเรียกใช้วิธี isterminaed จะกลับมาเป็นจริง สำหรับวิธีใดที่เราควรเรียกให้ปิดพูลเธรดควรกำหนดโดยลักษณะงานที่ส่งไปยังพูลเธรด โดยปกติแล้วการปิดเครื่องจะถูกเรียกให้ปิดพูลเธรด หากงานไม่จำเป็นต้องดำเนินการสามารถเรียกปิดเครื่องได้
3. การวิเคราะห์พูลเธรด
การวิเคราะห์กระบวนการ: เวิร์กโฟลว์หลักของพูลเธรดแสดงในรูปด้านล่าง: เวิร์กโฟลว์หลักของพูลเธรด Java
จากรูปด้านบนเราจะเห็นว่าเมื่อส่งงานใหม่ไปยังพูลเธรดโฟลว์การประมวลผลของพูลเธรดมีดังนี้:
** การวิเคราะห์ซอร์สโค้ด ** การวิเคราะห์กระบวนการข้างต้นช่วยให้เราเข้าใจหลักการทำงานของพูลเธรดได้อย่างสังหรณ์ใจ ให้เราใช้ซอร์สโค้ดเพื่อดูว่ามีการใช้งานอย่างไร พูลเธรดดำเนินงานดังนี้:
โมฆะสาธารณะดำเนินการ (คำสั่ง runnable) {ถ้า (command == null) โยน nullpointerexception ใหม่ (); int c = ctl.get (); if (workerCountof (c) <corepoolsize) {ถ้า (addworker (คำสั่ง, true)) กลับ; c = ctl.get (); } if (isrunning (c) && workqueue.offer (คำสั่ง)) {int recheck = ctl.get (); if (! isrunning (recheck) && ลบ (คำสั่ง)) ปฏิเสธ (คำสั่ง); อื่นถ้า (workerCountof (recheck) == 0) addworker (null, false); } อื่นถ้า (! addworker (คำสั่ง, false)) ปฏิเสธ (คำสั่ง);} ด้ายคนงาน เมื่อพูลเธรดสร้างเธรดมันจะห่อหุ้มเธรดลงในเธรดคนงาน หลังจากที่คนงานดำเนินงานแล้วมันจะวนรอบอย่างไม่มีที่สิ้นสุดเพื่อให้ได้งานในคิวงานเพื่อดำเนินการ
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น