เมื่อพัฒนาแอปพลิเคชันแบบมัลติเธรด เรามักจะต้องจัดการกับการจัดระเบียบการทำงานของเธรด ยิ่งแอปพลิเคชันของเรามีขนาดใหญ่ขึ้นและจำนวนเธรดที่เราต้องการสำหรับงานแบบมัลติเธรดก็ยิ่งมากขึ้นเท่านั้นเรียกใช้ได้วัตถุที่เราสร้างขึ้น

ควรสังเกตว่าการสร้างเธรดใน Java เป็นการดำเนินการที่ค่อนข้างแพง หากเราสร้างอินสแตนซ์ใหม่ของเธรดในแต่ละครั้งเพื่อดำเนินการ เราจะพบปัญหาใหญ่เกี่ยวกับประสิทธิภาพและผลที่ตามมาคือความสมบูรณ์ของแอปพลิเคชัน

Thread PoolและThreadPoolExecutorมาช่วยเราที่นี่

เธรดพูลคือชุดของเธรดที่เตรียมใช้งานล่วงหน้า ขนาดสามารถคงที่หรือเปลี่ยนแปลงได้

หากมีงานมากกว่าเธรด งานจะรออยู่ในคิวงาน เธรดที่ N ในพูลรับงานจากคิว และหลังจากเสร็จสิ้น เธรดจะรับงานใหม่จากคิว เมื่อดำเนินการงานทั้งหมดในคิวแล้ว เธรดจะยังคงทำงานอยู่และรองานใหม่ เมื่องานใหม่ปรากฏขึ้น เธรดจะเริ่มดำเนินการเช่นกัน

ThreadPoolExecutor

เริ่มต้นด้วย Java 5, Executor frameworkได้รับโซลูชันแบบมัลติเธรด โดยทั่วไป มีองค์ประกอบมากมายและจุดประสงค์คือช่วยให้เราจัดการคิวและเธรดพูลได้อย่างมีประสิทธิภาพ

อินเท อร์เฟซหลักคือExecutorและExecutorService

Executorเป็นอินเตอร์เฟสที่มีเมธอด execute(Runnable runnable) ตัวเดียว

เมื่อส่งงานไปยังการนำวิธีนี้ไปใช้ โปรดทราบว่ามันจะถูกดำเนินการแบบอะซิงโครนัสในอนาคต

ExecutorService — อินเทอร์เฟซที่ขยาย อิน เทอ ร์เฟซ Executor เพิ่มความสามารถในการดำเนินการ นอกจากนี้ยังมีวิธีการขัดจังหวะงานที่กำลังรันอยู่และยุติเธรดพูล

ThreadPoolExecutorใช้ อินเทอร์เฟซ Executorและ ExecutorServiceและแยกการสร้างงานออกจากการดำเนินการงาน เราจำเป็นต้องนำ วัตถุ ที่รันได้ไปใช้และส่งไปยังตัวดำเนินการ จากนั้น ThreadPoolExecutorจะรับผิดชอบในการดำเนินการงาน ตลอดจนสร้างและทำงานกับเธรด

หลังจากส่งงานเพื่อดำเนินการแล้ว เธรดที่มีอยู่ในพูลจะถูกใช้ สิ่งนี้ช่วยปรับปรุงประสิทธิภาพ มันแก้ปัญหาการสิ้นเปลืองทรัพยากรในการสร้างและเริ่มต้นเธรดใหม่ และอีกครั้งกับการรวบรวมขยะเมื่อเราทำเธรดเสร็จแล้ว

ThreadPoolExecutorมีตัวสร้าง 4 ตัว:


ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit, 
BlockingQueue<Runnable> workQueue)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory, 
RejectedExecutionHandler handler)
    

ตัว สร้าง ThreadPoolExecutorมีพารามิเตอร์ต่อไปนี้:

corePoolSize พารามิเตอร์นี้ระบุจำนวนเธรดที่จะพร้อม (เริ่มต้น) เมื่อบริการตัวดำเนินการเริ่มต้น
ขนาดสระสูงสุด จำนวนเธรดสูงสุดที่บริการตัวดำเนินการสามารถสร้างได้
KeepAliveTime เวลาที่เธรดอิสระจะยังคงอยู่ก่อนที่จะถูกทำลายหากจำนวนของเธรดมากกว่าcorePoolSize. มีการระบุหน่วยเวลาในพารามิเตอร์ถัดไป
หน่วย หน่วยเวลา (ชั่วโมง นาที วินาที มิลลิวินาที ฯลฯ)
คิวงาน การดำเนินการตามคิวสำหรับงาน
ตัวจัดการ ตัวจัดการสำหรับงานที่ไม่สามารถทำให้เสร็จได้
ด้ายโรงงาน วัตถุที่สร้างเธรดใหม่ตามต้องการ การใช้โรงงานเธรดจะทำให้การเรียกไปยังฮาร์ดแวร์เธรดใหม่เป็นอิสระ ทำให้แอปพลิเคชันสามารถใช้คลาสย่อยของเธรดพิเศษ ลำดับความสำคัญ และอื่นๆ

การสร้าง ThreadPoolExecutor

คลาส ยูทิลิตี้ Executorsสามารถทำให้การสร้างThreadPoolExecutorง่าย ขึ้น เมธอดของคลาสยูทิลิตี้นี้ช่วยให้เราเตรียมกThreadPoolExecutorวัตถุ.

newFixedThreadPool — สร้างกลุ่มเธรดที่นำเธรดจำนวนคงที่กลับมาใช้ใหม่เพื่อดำเนินการงานจำนวนเท่าใดก็ได้

ExecutorService executor = Executors.newFixedThreadPool(10);
                    
ใหม่WorkStealingPool — สร้างเธรดพูลโดยที่จำนวนเธรดเท่ากับจำนวนแกนประมวลผลที่มีใน JVM ระดับการทำงานพร้อมกันเริ่มต้นคือหนึ่ง ซึ่งหมายความว่าเธรดจำนวนมากจะถูกสร้างขึ้นในพูล เนื่องจากมีคอร์ CPU สำหรับ JVM หากระดับการทำงานพร้อมกันคือ 4 ค่าที่ส่งผ่านจะถูกใช้แทนจำนวนคอร์

ExecutorService executor = Executors.newWorkStealingPool(4);
                    
newSingleThreadExecutor — สร้างพูลด้วยเธรดเดียวเพื่อดำเนินการงานทั้งหมด

ExecutorService executor = Executors.newSingleThreadExecutor();
                    
newCachedThreadPool — สร้างเธรดพูลที่สร้างเธรดใหม่ตามต้องการ แต่นำเธรดที่สร้างไว้ก่อนหน้านี้กลับมาใช้ใหม่เมื่อพร้อมใช้งาน

ExecutorService executor = Executors.newCachedThreadPool();
                    
newScheduledThreadPool — สร้างเธรดพูลที่สามารถกำหนดเวลาคำสั่งให้ดำเนินการหลังจากเวลาที่กำหนดหรือเป็นระยะๆ

ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
                    

เราจะพิจารณาพูลแต่ละประเภทในบทเรียนต่อไปนี้