ThreadPoolExecutor - 1

"โปรแกรมเมอร์ทั่วไปไม่ช้าก็เร็วจะเข้าใจว่าพวกเขามีงานเล็กๆ น้อยๆ มากมายที่ต้องดำเนินการเป็นครั้งคราว"

"ถ้าคุณกำลังเขียนเกม มันคือการกระทำของตัวละครแต่ละตัว"

"หากคุณกำลังเขียนเว็บเซิร์ฟเวอร์ ผู้ใช้จะได้รับคำสั่งต่างๆ เช่น อัปโหลดรูปภาพ แปลงรหัสเป็นรูปแบบที่ต้องการ ใช้เทมเพลตที่ต้องการ เป็นต้น"

"ไม่ช้าก็เร็ว งานใหญ่ทั้งหมดจะถูกแบ่งออกเป็นงานย่อยๆ ที่จัดการได้"

"ดังนั้น เมื่อพิจารณาจากบริบทนี้ จึงเกิดคำถามเล็กๆ น้อยๆ ขึ้น: คุณควรจัดการงานทั้งหมดได้อย่างไร จะทำอย่างไรถ้าคุณต้องการทำงานหลายร้อยงานในหนึ่งนาที การสร้างเธรดสำหรับแต่ละงานคงไม่สมเหตุสมผลเท่าไหร่ เครื่อง Java จัดสรรทรัพยากรค่อนข้างมากสำหรับแต่ละเธรด"

"อีกนัยหนึ่ง การสร้างและทำลายเธรดอาจใช้เวลาและทรัพยากรมากกว่างานเอง"

"ผู้สร้างของ Java มาพร้อมกับวิธีแก้ปัญหาที่สวยงาม: ThreadPoolExecutor .

" ThreadPoolExecutorเป็นคลาสที่มีสองสิ่งอยู่ภายใน:"

A)  คิวงาน ซึ่งคุณสามารถเพิ่มงานเข้าไปได้เมื่อเกิดขึ้นในโปรแกรม

B)กลุ่มเธรดซึ่งเป็นกลุ่มของเธรดที่ทำงานเหล่านี้

"ยิ่งไปกว่านั้น เธรดจะไม่ถูกทำลายเมื่องานเสร็จสิ้น แต่จะเข้าสู่โหมดสลีปเพื่อให้พร้อมที่จะเริ่มงานใหม่ทันทีที่ปรากฏขึ้น"

"เมื่อคุณสร้างThreadPoolExecutorคุณสามารถตั้งค่าจำนวนสูงสุดของเธรดที่จะสร้างและจำนวนงานสูงสุดที่สามารถเข้าคิวได้ กล่าวอีกนัยหนึ่ง คุณสามารถจำกัดจำนวนของเธรดเป็น 10 ตัวอย่างเช่น และจำนวนของ จัดคิวงานเป็น 100"

"นี่คือวิธี การทำงาน ของ ThreadPoolExecutor :"

1)  เมื่อคุณเพิ่มงานใหม่ งานนั้นจะอยู่ที่ส่วนท้ายของคิว

2)  หากคิวเต็ม จะมีการยกเว้น

3)  เมื่อเสร็จสิ้นภารกิจ แต่ละเธรดจะรับภารกิจถัดไปจากคิวและเริ่มดำเนินการ

4)หากไม่มีงานในคิว เธรดจะเข้าสู่โหมดสลีปจนกว่าจะเพิ่มงานใหม่

"แนวทางที่เราจำกัดจำนวนเธรดผู้ปฏิบัติงานมีประโยชน์ตรงที่ยิ่งเรามีเธรดมาก เธรดก็ยิ่งรบกวนซึ่งกันและกัน การมีเธรดผู้ปฏิบัติงาน 5-10 เธรดและคิวงานยาวจะมีประสิทธิภาพมากกว่า เพื่อสร้าง 100 เธรดสำหรับงานที่เพิ่มขึ้น ซึ่งจะแข่งขันกันเพื่อแย่งชิงทรัพยากร: หน่วยความจำ เวลาประมวลผล การเข้าถึงฐานข้อมูล ฯลฯ"

"นี่คือตัวอย่างการทำงานของThreadPoolExecutor :"

ตัวอย่าง
ExecutorService service = Executors.newFixedThreadPool(2);

for(int i = 0; i < 10; i++)
{
 service.submit(new Runnable() {
    public void run()
    {
     // Here we download something big from the Internet.
    }
 });
}

“เอ่อ ไม่เห็น...”

" วัตถุ ThreadPoolExecutorถูกสร้างขึ้นเมื่อมีการเรียกใช้เมธอด newFixedThreadPool"

ดังนั้นจึงใช้งานง่ายมาก ทันทีที่คุณเพิ่มงานด้วยวิธีการส่ง มันจะ:

A)  ปลุกเธรดที่หลับอยู่ (ถ้ามี) เพื่อดำเนินงาน

B)  หากไม่มีเธรดรออยู่ เธรดจะสร้างเธรดใหม่สำหรับงาน

C)  หากถึงจำนวนเธรดสูงสุด ก็จะวางงานไว้ท้ายคิว

"ฉันจงใจใส่ «ที่นี่เราดาวน์โหลดอะไรใหญ่ๆ จากอินเทอร์เน็ต» ไว้ในตัวอย่าง ถ้าเรามีงาน 100 งาน «ดาวน์โหลดบางอย่างใหญ่ๆ จากอินเทอร์เน็ต» ก็ไม่มีเหตุผลที่จะเรียกใช้งานจำนวนมากในเวลาเดียวกัน—เรา' จะถูกจำกัดแบนด์วิธของการเชื่อมต่ออินเทอร์เน็ตของเรา ในกรณีนี้ แค่สองเธรดก็เพียงพอแล้ว นี่คือสิ่งที่คุณเห็นในตัวอย่างด้านบน:"

ExecutorService service = Executors.newFixedThreadPool(2);

"ปรากฎว่าการทำงานกับงานหลายอย่างไม่ใช่เรื่องยาก"

“ใช่ ง่ายกว่าที่คิด แต่คิมจะเล่าให้ฟัง”