เธรดพูลเป็นเครื่องมือที่ใช้งานได้จริงสำหรับการรวบรวมงานในแบบคู่ขนาน ด้วยการแนะนำสถาปัตยกรรมแบบหลายคอร์ที่เหมาะสมสำหรับการใช้งานแบบขนานแอปพลิเคชันบทบาทของสระว่ายน้ำเธรดเริ่มชัดเจนขึ้นเรื่อย ๆ ผ่านคลาส Threadpoolexecutor และคลาสเสริมอื่น ๆ Java 5 ได้แนะนำกรอบนี้เป็นส่วนสนับสนุนการเกิดพร้อมกันใหม่
เฟรมเวิร์ก ThreadPoolexecutor มีความยืดหยุ่นและทรงพลัง รองรับการกำหนดค่าเฉพาะของผู้ใช้และจัดเตรียมตะขอและนโยบายความอิ่มตัวที่เกี่ยวข้องเพื่อจัดการคิวเต็มรูปแบบ
พูลเธรด Java จะวางภารกิจที่ส่งมาก่อนในคิวการทำงานและรับพวกเขาจากคิวการทำงาน (Synchronousqueue ถูกส่งโดยตรงโดยผู้ผลิตไปยังเธรดการทำงาน) จากนั้นมีสองกลยุทธ์การดำเนินการสำหรับคิวการทำงาน: คิวที่ไม่มีขอบเขตและคิวที่มีขอบเขต ไม่มีปัญหาเกี่ยวกับความอิ่มตัวในคิวที่ไม่มีขอบเขต แต่ปัญหาคือเมื่อคำขอยังคงสูงงานจะถูกเพิ่มเข้าไปในคิวงานอย่างไม่น่าเชื่อซึ่งอาจทำให้หน่วยความจำและทรัพยากรอื่น ๆ ล้นหรือไอเสีย คิวที่มีขอบเขตจะไม่ทำให้หน่วยความจำอ่อนเพลียที่เกิดจากการโหลดสูง แต่มีปัญหาในการจัดการงานที่ส่งใหม่เมื่อคิวงานเต็ม นี่คือปัญหาที่กลยุทธ์ความอิ่มตัวของคิวพูลทำงานต้องแก้ปัญหา
กลยุทธ์ความอิ่มตัวถูกแบ่งออกเป็น: กลยุทธ์การยกเลิกกลยุทธ์ Callerruns กลยุทธ์ทิ้งและกลยุทธ์ Discardolds
เพื่อความเข้าใจที่ดีขึ้นฉันเขียนตัวอย่างเล็ก ๆ น้อย ๆ
แพ็คเกจพร้อมกันพูล; นำเข้า java.util.concurrent.linkedblockingdequ; นำเข้า java.util.concurrent.rejectedexecutionhandler; นำเข้า java.util.concurrent.threadpoolexecutor; นำเข้า java.util.concurrent.timeunit ภายใต้นโยบายความอิ่มตัวที่แตกต่างกัน* @param Handler Thread Pool Work นโยบายความอิ่มตัวของพูล*/นโยบายโมฆะคงที่สาธารณะ (ปฏิเสธ Handler Handler) {// มี 2 เธรดพื้นฐานจำนวนมากที่สุดของเธรดคือ 3 และความสามารถในการทำงานของคิว LinkedBlockingDeque <> (5)); if (handler! = null) {exec.setRejectedExecutionHandler (Handler); // กำหนดนโยบายความอิ่มตัว} สำหรับ (int i = 0; i <10; i ++) {exec.submit threadpoolexecutor.abortpolicy ()); // นโยบาย ((ใหม่ threadpoolexecutor.callerrunspolicy ())); // นโยบาย (ใหม่ threadpoolexecutor.discardpolicy (); // นโยบาย (threadpoolexecutordorment id = 0; // task id งานสาธารณะ () {id = ++ count;}@การแทนที่โมฆะสาธารณะเรียกใช้ () {ลอง {timeunit.seconds.sleep (3); // นอนเป็นเวลา 3 วินาที} จับ (interruptedException e) {system.err.println ( "/t worker thread:" + thread.currentthread (). getName () + "การดำเนินการเสร็จสมบูรณ์");}}} เมื่อคิวการทำงานเต็มกลยุทธ์ที่แตกต่างจะได้รับการจัดการดังนี้:
1. นโยบายการปฏิบัติ: นโยบายเริ่มต้น เมื่อมีการส่งงานใหม่ข้อยกเว้นที่ไม่ได้ทำการตรวจสอบจะถูกโยนโดยตรง ผู้โทรสามารถจับได้
เพิ่มรหัสต่อไปนี้ในฟังก์ชั่นหลัก:
นโยบาย (ใหม่ threadpoolexecutor.abortpolicy ());
ผลการดำเนินการคือ:
โปรแกรมส่งผลงานที่ถูกปฏิเสธการรับรู้และการทำงานทั้งหมด 8 งาน (พูลเธรดสามารถเรียกใช้งาน 3 งานที่จุดเริ่มต้นและเก็บคิว 5 คิวในคิวงาน) เมื่อคิวการทำงานเต็มไปด้วยข้อยกเว้นจะถูกโยนโดยตรงและ JVM ไม่ออก (ฉันไม่รู้ว่าทำไมตอนนี้) เราจะเห็นว่าเธรดทั้งหมดที่ดำเนินการงานเป็นเธรดในพูลเธรด
2. กลยุทธ์ Callerruns: สำหรับกลไกการปรับตัวไม่ละทิ้งงานหรือโยนข้อยกเว้น แต่กลับไปหาผู้โทร งานใหม่ไม่ได้ดำเนินการในพูลเธรด แต่ในเธรดเรียกว่า exector
ทำงานในฟังก์ชั่นหลัก:
นโยบาย ((ใหม่ threadpoolexecutor.callerrunspolicy ()));
การรันผลลัพธ์
งานทั้งหมดทำงานและ 2 (10 - 3 -5) งานจะดำเนินการสำเร็จในเธรดหลักและ 8 งานจะดำเนินการโดยเธรดในพูลเธรด
3. กลยุทธ์การเรียนรู้: งานที่ส่งใหม่ถูกทอดทิ้ง
รันในฟังก์ชั่นหลัก
นโยบาย (ใหม่ threadpoolexecutor.discardpolicy ());
ผลลัพธ์ข้างต้นแสดงให้เห็นว่าไม่มีข้อยกเว้นถูกโยนทิ้งงานใหม่ 2 รายการที่ส่งมาในภายหลังจะถูกยกเลิกและมีการประมวลผลเฉพาะงาน 8 (3+5) เท่านั้นและออกจาก JVM
4. กลยุทธ์ที่ดีที่สุด: คิวเป็นงานของ "หัวหน้าทีม" จากนั้นพยายามส่งงานใหม่ (ไม่เหมาะสำหรับสถานการณ์คิวงานเป็นคิวลำดับความสำคัญ)
เรียกใช้วิธีการต่อไปนี้ในฟังก์ชันหลัก
นโยบาย (ใหม่ threadpoolexecutor.discardoldestpolicy ());
ผลการทำงาน: มี 8 งานที่ทำงานทั้งหมด โปรแกรมสิ้นสุดลง งานที่เพิ่มขึ้นในภายหลังคือ 9 และ 10 ในขณะที่งานก่อนหน้า 3 และ 4 จะถูกยกเลิก
สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้เกี่ยวกับตัวอย่างรหัสของกลยุทธ์การทำงานของพูลพูล Java ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้