สถานะของเธรด
แผนภาพสถานะเธรด:
ภาพประกอบ:
เธรดรวมถึง 5 สถานะต่อไปนี้
1. สถานะใหม่ : หลังจากสร้างวัตถุเธรดแล้วมันจะเข้าสู่สถานะใหม่ ตัวอย่างเช่นเธรดเธรด = เธรดใหม่ ()
2. Runnable: ยังเป็นที่รู้จักกันในชื่อ "สถานะการดำเนินการ" หลังจากสร้างวัตถุเธรดเธรดอื่น ๆ เรียกเมธอดเริ่มต้น () ของวัตถุเพื่อเริ่มเธรด ตัวอย่างเช่น thread.start () เธรดในสถานะพร้อมอาจถูกกำหนดให้ดำเนินการโดย CPU ได้ตลอดเวลา
3. สถานะการรัน: เธรดได้รับสิทธิ์ CPU สำหรับการดำเนินการ ควรสังเกตว่าเธรดสามารถป้อนสถานะการทำงานจากสถานะพร้อมเท่านั้น
4. สถานะที่ถูกบล็อก: สถานะที่ถูกบล็อกหมายความว่าเธรดจะให้สิทธิ์การใช้งาน CPU ด้วยเหตุผลบางอย่างและหยุดทำงานชั่วคราว มันไม่ได้จนกว่าเธรดจะเข้าสู่สถานะพร้อมที่จะมีโอกาสไปที่สถานะการวิ่ง การอุดตันมีสามประเภท:
(1) รอบล็อก - โดยเรียกเมธอดการรอของเธรด () ให้เธรดรอให้เสร็จงานบางอย่าง
(2) การปิดกั้นแบบซิงโครไนซ์-เธรดไม่สามารถรับการล็อคซิงโครไนซ์ซิงโครไนซ์ (เนื่องจากล็อคถูกครอบครองโดยเธรดอื่น ๆ ) มันจะเข้าสู่สถานะการปิดกั้นแบบซิงโครไนซ์
(3) การปิดกั้นอื่น ๆ-เธรดจะเข้าสู่สถานะการบล็อกโดยเรียก Sleep () หรือเข้าร่วม () ของเธรดหรือออกคำขอ I/O เมื่อสถานะการนอนหลับ () หมดเวลาเข้าร่วม () รอให้เธรดยุติหรือหมดเวลาหรือการประมวลผล I/O เสร็จสิ้นเธรดจะกลับเข้าสู่สถานะพร้อมอีกครั้ง
5. สถานะ Dead: เธรดเสร็จสิ้นการดำเนินการหรือออกจากวิธีการเรียกใช้ () เนื่องจากข้อยกเว้นและเธรดจะสิ้นสุดวัฏจักรชีวิต
เนื้อหาที่เกี่ยวข้องใน 5 สถานะเหล่านี้รวมถึงคลาสวัตถุเธรดและคำหลักที่ซิงโครไนซ์ เราจะเรียนรู้เนื้อหาเหล่านี้ทีละคนในบทต่อไปนี้
คลาสวัตถุกำหนดฟังก์ชั่นการนอนหลับ/ตื่นเช่น wait (), แจ้ง (), notifyall () ฯลฯ
คลาสเธรดกำหนดฟังก์ชั่นการทำงานของเธรดคอลัมน์ ตัวอย่างเช่นฟังก์ชั่นการนอนหลับ sleep (), interrupt () ฟังก์ชั่นขัดจังหวะ, getName () รับชื่อเธรด ฯลฯ
ซิงโครไนซ์เป็นคำหลัก มันโดดเด่นด้วยบล็อกรหัสที่ซิงโครไนซ์และวิธีการซิงโครไนซ์ ฟังก์ชั่นของการซิงโครไนซ์คือการอนุญาตให้เธรดได้รับการล็อคการซิงโครไนซ์ของวัตถุ
เมื่อเราแนะนำการรอ (), แจ้ง () และวิธีการอื่น ๆ โดยละเอียดในภายหลังเราจะวิเคราะห์ว่าทำไม "รอ (), แจ้ง () และวิธีอื่น ๆ ควรกำหนดไว้ในคลาสวัตถุไม่ใช่คลาสเธรด"
สองวิธีในการใช้มัลติเธรด: เธรดและรันได้
Runnable เป็นอินเทอร์เฟซที่มีวิธีเดียว Run () คำจำกัดความของมันมีดังนี้:
อินเทอร์เฟซสาธารณะ runnable {public abstract void run ();} บทบาทของ Runnable, ใช้หลายเธรด เราสามารถกำหนดคลาส A เพื่อใช้อินเตอร์เฟสที่เรียกใช้ได้ จากนั้นสร้างเธรดใหม่ผ่านเธรดใหม่ (ใหม่ A ()) และวิธีอื่น ๆ
เธรดเป็นคลาส เธรดเองใช้อินเทอร์เฟซที่รันได้ คำแถลงของมันมีดังนี้:
เธรดคลาสสาธารณะใช้งาน Runnable {}
บทบาทของเธรดคือการตระหนักถึงมัลติเธรด
ความเหมือนและความแตกต่างระหว่างเธรดและ runnable:
ความคล้ายคลึงกันระหว่างเธรดและ Runnable: ทั้งคู่เป็น“ วิธีการใช้งานแบบหลายเธรด”
ความแตกต่างระหว่างเธรดและ runnable:
เธรดเป็นคลาสและ Runnable เป็นอินเทอร์เฟซ เธรดเองเป็นคลาสที่ใช้อินเทอร์เฟซที่รันได้ เรารู้ว่า "คลาสสามารถมีคลาสพาเรนต์เดียวเท่านั้น แต่สามารถใช้หลายอินเทอร์เฟซ" ดังนั้น Runnable จึงมีความสามารถในการปรับขนาดได้ดีขึ้น
นอกจากนี้ยังสามารถใช้งานได้สำหรับ "การแบ่งปันทรัพยากร" นั่นคือหลายเธรดถูกสร้างขึ้นตามวัตถุที่รันได้บางอย่างและพวกเขาจะแบ่งปันทรัพยากรบนวัตถุที่รันได้
โดยทั่วไปขอแนะนำให้ใช้มัลติเธรดผ่าน "runnable"!
ตัวอย่างมัลติเธรดสำหรับเธรดและรันได้
1. ตัวอย่างมัลติเธรดของเธรด
ด้านล่างเราสามารถเข้าใจเธรดและรันได้ดีขึ้นผ่านตัวอย่างและวาดตัวอย่างออนไลน์ที่น่าเชื่อถือมากขึ้น // threadtest.java ซอร์ส
Class MyThread ขยายเธรด {ตั๋ว INT ส่วนตัว = 10; โมฆะสาธารณะเรียกใช้ () {สำหรับ (int i = 0; i <20; i ++) {ถ้า (this.ticket> 0) {system.out.println (this.getName ()+"ตั๋ว: ตั๋ว"+this.ticket--); }}}}}}; Threadtest คลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// เริ่ม 3 เธรด t1, t2, t3; แต่ละเธรดขายตั๋ว 10 ใบ! MYTHREAD T1 = ใหม่ MYTHREAD (); MYTHREAD T2 = ใหม่ MYTHREAD (); MYTHREAD T3 = ใหม่ MYTHREAD (); t1.start (); t2.start (); t3.start (); - ผลการทำงาน:
การขายตั๋ว THRIDE-0: Ticket10Thread-1 ตั๋วขาย: Ticket10Thread-2 ตั๋วขาย: ตั๋ว 10THREAD-1 ตั๋วขาย: Ticket9THREAD-0 Ticket Selling: Ticket9Thread-1 Ticket Selling: Ticket8Thread-2 ตั๋วขาย: ขายตั๋ว -1 ตั๋ว Ticket7Thread-1 ตั๋วขาย: Ticket4Thread-2 ตั๋วขาย: Ticket7Thread-1 ตั๋วขาย: Ticket3Thread-0 ตั๋ว: Ticket6Thread-1 ตั๋ว: Ticket2Thread-2 Tickets: Ticket6Thread-2 ตั๋ว: Ticket5Thread-2 Tickets: Tickets: Tickets: Tickets: Ticket: Tickets ตั๋ว: Ticket3Thread-0 ตั๋ว: Ticket1Thread-0 ตั๋ว: Ticket2thread-0 ตั๋ว: ตั๋ว 1thread-0 ตั๋ว: Ticket2thread-0 ตั๋ว: ตั๋ว 1
ผลลัพธ์คำอธิบาย:
(1) MyThread สืบทอดมาจากเธรดซึ่งเป็นเธรดที่กำหนดเอง แต่ละตำนานขายตั๋ว 10 ใบ
(2) เธรดหลักหลักสร้างและเริ่มต้น 3 เธรดเด็ก MyThread กระทู้เด็กแต่ละคนขายตั๋ว 10 ใบ
2. ตัวอย่างมัลติเธรดของ runnable
ต่อไปเราแก้ไขโปรแกรมข้างต้น ใช้อินเทอร์เฟซผ่าน Runnable ซึ่งจะใช้การทำมัลติเธรด
// runnableTest.java คลาสซอร์สโค้ดคลาส MyThread ใช้งาน runnable {ตั๋ว INT ส่วนตัว = 10; โมฆะสาธารณะเรียกใช้ () {สำหรับ (int i = 0; i <20; i ++) {ถ้า (this.ticket> 0) {system.out.println (thread.currentthread (). getName ()+"ขายตั๋ว: ตั๋ว" - คลาสสาธารณะ runnableTest {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {mythread mt = new mythread (); // เริ่มต้น 3 เธรด T1, T2, T3 (พวกเขาแบ่งปันวัตถุที่รันได้) และ 3 เธรดเหล่านี้ขายตั๋วทั้งหมด 10 ใบ! เธรด t1 = เธรดใหม่ (mt); เธรด t2 = เธรดใหม่ (mt); เธรด t3 = เธรดใหม่ (mt); t1.start (); t2.start (); t3.start (); - ผลการทำงาน:
การขายตั๋ว Thread-0: Ticket10Thread-2 ตั๋วขาย: Ticket8Thread-1 ตั๋วขาย: Ticket9Thread-2 ตั๋วขาย: Ticket6Thread-0 ขายตั๋ว: Ticket7Thread-2 ตั๋วขาย: Ticket4Thread-1 ตั๋วขาย: Ticket5Thread-2 ตั๋วขายตั๋ว: ตั๋ว Ticket2Thread-0
ผลลัพธ์คำอธิบาย:
(1) ไม่เหมือน "Mythread สืบทอดมาจากเธรด" ข้างต้น; ที่นี่ MyThread ใช้อินเทอร์เฟซเธรด
(2) เธรดหลักจะสร้างและเริ่มเธรดเด็ก 3 เธรดและเธรดลูกทั้ง 3 นี้ถูกสร้างขึ้นตาม "MT, Runnable Object" ผลของการดำเนินการคือเธรดเด็ก 3 ตัวนี้ขายตั๋วทั้งหมด 10 ใบ ซึ่งหมายความว่าพวกเขาแบ่งปันอินเทอร์เฟซ MyThread