
"โปรแกรมเมอร์ทั่วไปไม่ช้าก็เร็วจะเข้าใจว่าพวกเขามีงานเล็กๆ น้อยๆ มากมายที่ต้องดำเนินการเป็นครั้งคราว"
"ถ้าคุณกำลังเขียนเกม มันคือการกระทำของตัวละครแต่ละตัว"
"หากคุณกำลังเขียนเว็บเซิร์ฟเวอร์ ผู้ใช้จะได้รับคำสั่งต่างๆ เช่น อัปโหลดรูปภาพ แปลงรหัสเป็นรูปแบบที่ต้องการ ใช้เทมเพลตที่ต้องการ เป็นต้น"
"ไม่ช้าก็เร็ว งานใหญ่ทั้งหมดจะถูกแบ่งออกเป็นงานย่อยๆ ที่จัดการได้"
"ดังนั้น เมื่อพิจารณาจากบริบทนี้ จึงเกิดคำถามเล็กๆ น้อยๆ ขึ้น: คุณควรจัดการงานทั้งหมดได้อย่างไร จะทำอย่างไรถ้าคุณต้องการทำงานหลายร้อยงานในหนึ่งนาที การสร้างเธรดสำหรับแต่ละงานคงไม่สมเหตุสมผลเท่าไหร่ เครื่อง 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);
"ปรากฎว่าการทำงานกับงานหลายอย่างไม่ใช่เรื่องยาก"
“ใช่ ง่ายกว่าที่คิด แต่คิมจะเล่าให้ฟัง”
GO TO FULL VERSION