ค่าใช้จ่ายในการเริ่มต้นเธรดในระบบค่อนข้างสูงเนื่องจากเกี่ยวข้องกับการมีปฏิสัมพันธ์กับระบบปฏิบัติการ ข้อดีของการใช้พูลเธรดคือการปรับปรุงประสิทธิภาพ เมื่อระบบมีเธรดที่เกิดขึ้นพร้อมกันจำนวนมากมันจะทำให้ประสิทธิภาพของระบบลดลงอย่างรวดเร็วและทำให้ JVM พัง จำนวนเธรดสูงสุดในพารามิเตอร์พูลเธรดสามารถควบคุมจำนวนเธรดพร้อมกันในระบบไม่เกินจำนวนครั้ง
1. คลาสโรงงานผู้บริหารใช้เพื่อสร้างพูลเธรด คลาสโรงงานนี้มีวิธีการโรงงานคงที่ต่อไปนี้เพื่อสร้างพูลเธรดที่สอดคล้องกัน พูลเธรดที่สร้างขึ้นเป็นวัตถุ ExecutorService วิธีการส่งของวัตถุหรือวิธีการดำเนินการเพื่อดำเนินการงานที่ทำงานได้หรือเรียกใช้งานได้ พูลเธรดเองเรียกวิธีการปิด () เพื่อหยุดพูลเธรดเมื่อไม่จำเป็นต้องใช้อีกต่อไป หลังจากโทรหาวิธีการพูลเธรดจะไม่อนุญาตให้เพิ่มงานอีกต่อไป แต่จะไม่ตายจนกว่างานที่เพิ่มทั้งหมดจะถูกดำเนินการ
1. NewCachedThreadPool () สร้างพูลเธรดที่มีฟังก์ชั่นแคชและส่งเธรดที่สร้างขึ้นโดยงาน (วัตถุที่เรียกใช้หรือเรียกได้) ของพูลเธรด หากการดำเนินการเสร็จสมบูรณ์จะถูกแคชลงใน CachedThreadPool เพื่อใช้งานที่ต้องดำเนินการในภายหลัง
นำเข้า java.util.concurrent.executorservice; นำเข้า java.util.concurrent.executors; คลาสสาธารณะ cachethreadpool {งานคลาสคงที่ใช้งานได้ {@Override void run () {system.out.println (this.currentthread () thread.currentthread (). getAllStackTraces (). size ()); }} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {executorService cachethreadPool = executors.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 (งานใหม่ ()); -ผลการดำเนินการมีดังนี้:
cachethreadpool $ task@2d312eb9 pool-1-thread-1 Allstacktraces ขนาดแผนที่: 7CachetHreadPool $ task@59522B86 POOL-1-Thread-3 AllStackTraces ขนาดแผนที่: 7CACHETHREADPOOL $ task พูล -1-Thread-3 AllStackTraces ขนาดแผนที่: 7CachetHreadPool $ task@256D5600 POOL-1-Thread-1 AllStackTraces ขนาดแผนที่: 7CachetHreadPool $ task@7D1C5894 POLIN-1-Thread-2 AllStackTraces ขนาดแผนที่: 7
วัตถุเธรดในพูลเธรดจะถูกแคชและนำกลับมาใช้ใหม่เมื่อมีการดำเนินการใหม่ อย่างไรก็ตามหากมีการเกิดขึ้นพร้อมกันจำนวนมากพูลเธรดแคชจะยังคงสร้างวัตถุเธรดจำนวนมาก
2. Newfixedthreadpool (int nthreads) สร้างพูลเธรดที่มีจำนวนเธรดที่ระบุซึ่งสามารถนำกลับมาใช้ใหม่ได้โดยเธรด
นำเข้า java.util.concurrent.executorservice; นำเข้า java.util.concurrent.executors; คลาสสาธารณะคงที่ {งานคลาสคงที่ใช้งานได้ {@Override public void run () {system.out.println (this + " +" + " thread.currentthread (). getAllStackTraces (). size ()); }} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {executoRservice impedThreadPool = executors.newFixedThreadPool (3); // ก่อนเพิ่มสามงานลงในพูลเธรดสำหรับ (int i = 0; i <5; i ++) {recidethreadpool.execute (งานใหม่ ()); } // หลังจากมีการดำเนินการทั้งสามเธรดแล้วเพิ่มสามงานลงในพูลเธรดอีกครั้งลอง {thread.sleep (3); } catch (interruptedException e) {e.printStackTrace (); } สำหรับ (int i = 0; i <3; i ++) {recidethreadpool.execute (งานใหม่ ()); -ผลการดำเนินการ:
recideThreadPool $ task@7045C12D POOL-1-Thread-2 AllStackTraces ขนาดแผนที่: 7FixedThreadPool $ task@50FA0BEF พูล -1-Thread-2 AllStackTraces ขนาดแผนที่: 7FixedTHREADPOOL $ TASK@CCB1870 POOL-THREAD-2 AllStackTraces ขนาดแผนที่: 7FixedThreadPool $ task@5BDEFF18 POOL-1-Thread-2 AllStackTraces ขนาดแผนที่: 7FixedThreadPool $ task@7d5554E1 Pool-1-Thread-1 Allstacktraces ขนาด: 7FixedThreadPool 7FixedThreadPool $ task@fa7b978 pool-1-thread-2 allstacktraces ขนาดแผนที่ขนาด: 7
3. NewsingLetHreadExecutor () สร้างพูลเธรดที่มีเธรดเดี่ยวเท่านั้นซึ่งเทียบเท่ากับการโทร NewFixedThreadPool (1)
4. NewsheduledThreadpool (int corepoolsize) สร้างพูลเธรดที่มีจำนวนเธรดที่ระบุซึ่งสามารถเรียกใช้เธรดหลังจากการหน่วงเวลาที่ระบุ นอกจากนี้คุณยังสามารถทำซ้ำเธรดได้ในช่วงเวลาหนึ่งโดยรู้ว่าคุณสามารถโทรปิด () เพื่อปิดพูลเธรด
ตัวอย่างมีดังนี้:
นำเข้า java.util.concurrent.executors; นำเข้า java.util.concurrent.scheduledexecutorservice; นำเข้า java.util.concurrent.timeUnit; System.currentTimeMillis () + "" + thread.currentThread (). getName () + "AllStackTraces ขนาดแผนที่:" + thread.currentThread (). getAllStackTraces (). size ()); }} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {ScheduleDexecutorService ScheduleDexecutorService = Executors.newscheduledThreadPool (3); ScheduleDexecutorservice.Schedule (งานใหม่ (), 3, TimeUnit.Seconds); ScheduleDexecutorservice.ScheduleatFixedrate (งานใหม่ (), 3, 5, TimeUnit.Seconds); ลอง {thread.sleep (30 * 1000); } catch (interruptedException e) {e.printStackTrace (); } ScheduleDexecutorService.shutdown (); -ผลการดำเนินการมีดังนี้:
เวลา 1458921795240 พูล -1-Thread-1 Allstacktraces ขนาดแผนที่: 6time 1458921795241 Pool-1-Thread-2 Allstacktraces ขนาดแผนที่: 6time 1458921800240 Pool-1-Thread-1 Allstacktraces 1458921810240 พูล -1-Thread-1 AllstackTraces ขนาดแผนที่: 7TIE 1458921815240 POLIN-1-Thread-1 AllStackTraces ขนาดแผนที่: 7 เวลา 1458921820240 POLIN-1-Thread-1 AllStackTraces ขนาดแผนที่: 7 7
ดังที่เห็นได้จากเวลาทำงานงานจะถูกดำเนินการในรอบ 5 วินาที
5. NewsingLetHreadsCheduledExecutor () สร้างพูลเธรดที่มีเธรดเพียงหนึ่งเธรดและเรียก NewscheduledThreadPool (1)
2. ForkJoinpool และ Forkjointask
ForkJoinpool เป็นคลาสการใช้งานของ ExecutorService รองรับการแบ่งงานออกเป็นงานขนาดเล็กหลายรายการในการคำนวณแบบขนานและรวมผลการคำนวณของงานขนาดเล็กหลายรายการไว้ในผลการคำนวณทั้งหมด มีสองตัวสร้าง
ForkJoinpool (Int Parallelism) สร้าง forkjoinpool ที่มีเธรดคู่ขนาน
ForkJoinpool () สร้าง ForkJoinPool โดยใช้ค่าคืนค่าของ runtime.availableProcessors () เป็นพารามิเตอร์คู่ขนาน
Forkjointask แสดงถึงงานที่สามารถขนานและรวมเข้าด้วยกัน มันเป็นคลาสนามธรรมที่ใช้อินเทอร์เฟซ <T> ในอนาคต มันมีสองคลาสย่อยที่เป็นนามธรรมซึ่งแสดงถึงการทำซ้ำของงานโดยไม่มีค่าส่งคืนและ Recursivetask ที่มีค่าส่งคืน คุณสามารถสืบทอดคลาสนามธรรมทั้งสองนี้ตามความต้องการเฉพาะในการใช้วัตถุของคุณเองจากนั้นเรียกใช้วิธีการส่งของ ForkJoinpool เพื่อดำเนินการ
ตัวอย่าง recuriveaction มีดังนี้การใช้เอาต์พุตแบบขนานของตัวเลข 0-300
นำเข้า java.util.concurrent.forkjoinpool; นำเข้า java.util.concurrent.recursiveaction; นำเข้า java.util.concurrent.timeunit; คลาสสาธารณะ Actionforkjointask เริ่มต้น INT ส่วนตัว จุดสิ้นสุด int ส่วนตัว; Public PrintTask (int start, int end) {this.start = start; this.end = สิ้นสุด; } @Override Void Pomid Compute () {if (end - start <threshold) {สำหรับ (int i = start; i <end; i ++) {system.out.println (thread.currentthread (). getName () + "" + i); }} else {int middle = (start + end) / 2; printtask left = new printtask (เริ่มต้นกลาง); printtask ขวา = printtask ใหม่ (กลาง, สิ้นสุด); left.fork (); Right.fork (); }}} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {forkjoinpool pool = new forkjoinpool (); pool.submit (printtask ใหม่ (0, 300)); ลอง {pool.awaittermination (2, TimeUnit.seconds); } catch (interruptedException e) {e.printStackTrace (); } pool.shutdown (); -หลังจากแยกงานเล็ก ๆ ให้เรียกใช้วิธีการส้อม () ของงานและเพิ่มลงใน ForkJoinpool เพื่อดำเนินการแบบขนาน
ตัวอย่าง Recursivetask ใช้การคำนวณแบบขนานของจำนวนเต็ม 100 ตัวเพื่อรวม แบ่งออกเป็นทุก ๆ 20 ตัวเลขและสรุปเพื่อให้ได้ผลลัพธ์และรวมเข้ากับผลลัพธ์สุดท้ายในตอนท้าย
นำเข้า java.util.random; นำเข้า java.util.concurrent.executionexception; นำเข้า java.util.concurrent.forkjoinpool; นำเข้า java.util.concurrent.future; นำเข้า java.util.Current.Recursivetask; เกณฑ์ int สุดท้ายคงที่ส่วนตัว = 20; ส่วนตัว int arr []; เริ่มต้น INT ส่วนตัว จุดสิ้นสุด int ส่วนตัว; Public Caltask (int [] arr, int start, int end) {this.arr = arr; this.start = เริ่ม; this.end = สิ้นสุด; } @Override Protected Integer Compute () {int sum = 0; if (end - start <threshold) {สำหรับ (int i = start; i <end; i ++) {sum+= arr [i]; } system.out.println (thread.currentthread (). getName () + "ผลรวม:" + ผลรวม); ผลรวมกลับ; } else {int middle = (start + end) / 2; Caltask left = new Caltask (arr, start, middle); Caltask Right = New Caltask (arr, middle, end); left.fork (); Right.fork (); return left.oin () + ขวา. join (); }}} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {int arr [] = new int [100]; สุ่มสุ่ม = ใหม่สุ่ม (); int ทั้งหมด = 0; สำหรับ (int i = 0; i <arr.length; i ++) {int tmp = random.nextint (20); ทั้งหมด += (arr [i] = tmp); } system.out.println ("รวม" + รวม); ForkJoinPool Pool = New ForkJoinpool (4); อนาคต <integer> future = pool.submit (ใหม่ Caltask (arr, 0, arr.length)); ลอง {system.out.println ("ผลลัพธ์ CAL:" + future.get ()); } catch (interruptedException e) {e.printStackTrace (); } catch (executionException) e) {e.printStackTrace (); } pool.shutdown (); -ผลการดำเนินการมีดังนี้:
รวม 912ForkJoinpool-1-Worker-2 ผลรวม: 82ForkJoinpool-1-Worker-2 Sum: 123ForkJoinpool-1-Worker-2 SUM: 144ForkJoinpool-1-Worker-3 ผลรวม: 119ForkJoinpool-1-Worker-2 SUM: 106ForkJoinpool-1-Worker-28 ผลรวม: 121ForkJoinpool-1-Worker-3 ผลรวม: 89Cal ผล: 912
หลังจากใช้งาน subtask ให้เรียกใช้วิธีการเข้าร่วม () ของงานเพื่อให้ได้ผลการดำเนินการ subtask จากนั้นเพิ่มเพื่อให้ได้ผลลัพธ์สุดท้าย