บทความนี้เป็นไปตามบทความก่อนหน้านี้ "คำอธิบายโดยละเอียดของตัวอย่าง Java multithreading (i)"
4. สถานะการบล็อกและการควบคุมเธรดของ Java multithreads
การปิดกั้น Java หลายประเภทได้รับการกล่าวถึงข้างต้น ลองมาดูวิธีการหลักที่ทำให้เกิดการอุดตันเธรด Java
1.Join ()
เข้าร่วม - ให้หนึ่งเธรดหนึ่งรอให้เธรดอื่นเสร็จสมบูรณ์ก่อนดำเนินการดำเนินการต่อ หากเธรด A ถูกเรียกในเมธอดการเข้าร่วมของเธรด B () ในการทำงานของเธรดเธรด A จะถูกบล็อกและหลังจากที่เธรด B เป็นที่รู้จักกันว่าเสร็จสิ้นการดำเนินการของเธรด B เสร็จสิ้น A สามารถดำเนินการต่อไปได้
Public Class Threadtest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {myrunnable myrunnable = new myrunnable (); เธรด = เธรดใหม่ (myrunnable); สำหรับ (int i = 0; i <100; i ++) {system.out.println (thread.currentthread (). getName () + "" + i); if (i == 30) {thread.start (); ลอง {thread.oin (); // เธรดหลักต้องรอเธรดเธรดเพื่อดำเนินการก่อนที่จะดำเนินการต่อเพื่อดำเนินการ} catch (interruptedException e) {e.printStackTrace (); -2.Sleep ()
Sleep - ให้การดำเนินการในปัจจุบันของเธรดหยุดเวลาที่กำหนดและป้อนสถานะการบล็อก ในช่วงระยะเวลาที่มันหลับเธรดจะไม่ได้รับโอกาสในการดำเนินการเพราะมันไม่ได้อยู่ในสถานะพร้อม แม้ว่าจะไม่มีเธรดที่ใช้งานได้อื่นในระบบในเวลานี้เธรดใน Sleep () จะไม่ทำงาน ดังนั้นวิธีการนอนหลับ () มักจะใช้เพื่อหยุดการทำงานของเธรดชั่วคราว
ดังที่ได้กล่าวไว้ก่อนหน้านี้เมื่อวิธีการเริ่มต้น () ของเธรดที่สร้างขึ้นใหม่นั้นเรียกว่าเธรดจะเข้าสู่สถานะพร้อมและอาจได้รับชิ้นเวลา CPU ในบางครั้งเพื่อดำเนินการ หากคุณต้องการให้เธรดใหม่ดำเนินการทันทีด้วยความจำเป็นบางอย่างเพียงแค่โทรไปที่ Sleep (1) ของเธรดต้นฉบับโดยตรง
Public Class Threadtest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {myrunnable myrunnable = new myrunnable (); เธรด = เธรดใหม่ (myrunnable); สำหรับ (int i = 0; i <100; i ++) {system.out.println (thread.currentthread (). getName () + "" + i); if (i == 30) {thread.start (); ลอง {thread.sleep (1); // ทำให้เธรดแน่ใจว่าจะดำเนินการทันที} catch (interruptedException e) {e.printstacktrace (); -หมายเหตุ: การนอนหลับเป็นเวลาหนึ่งมิลลิวินาทีก็เพียงพอแล้วเพราะ CPU จะไม่ว่างและจะเปลี่ยนเป็นเธรดที่สร้างขึ้นใหม่
3. เธรดพื้นหลัง (เธรด daemon)
แนวคิด/วัตถุประสงค์: เธรดพื้นหลังส่วนใหญ่ให้บริการกับเธรดอื่น ๆ (ค่อนข้างเรียกว่าหัวข้อเบื้องหน้า) หรือ "เธรด daemon" เช่นเธรดคอลเลกชันขยะใน JVM
วงจรชีวิต: วงจรชีวิตของเธรดพื้นหลังเกี่ยวข้องกับวงจรชีวิตของด้ายเบื้องหน้า มันสะท้อนออกมาเป็นหลักใน: เมื่อเธรดเบื้องหน้าทั้งหมดเข้าสู่สถานะตายด้ายพื้นหลังจะตายโดยอัตโนมัติ (ในความเป็นจริงนี่เป็นเรื่องง่ายที่จะเข้าใจเพราะจุดประสงค์ของเธรดพื้นหลังคือการให้บริการด้ายเบื้องหน้าเนื่องจากหัวข้อเบื้องหน้าทั้งหมดเสียชีวิต
การตั้งค่าเธรดพื้นหลัง: การเรียกใช้เมธอด setDaemon (จริง) ของวัตถุเธรดสามารถตั้งค่าเธรดที่ระบุเป็นเธรดพื้นหลัง
Public Class Threadtest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {เธรด MyThread = new MyThread (); สำหรับ (int i = 0; i <100; i ++) {system.out.println ("เธรดหลัก i ="+i); if (i == 20) {mythread.setdaemon (จริง); mythread.start (); }}}}} คลาส MyThread ขยายเธรด {โมฆะสาธารณะ run () {สำหรับ (int i = 0; i <100; i ++) {system.out.println ("i ="+i); ลอง {thread.sleep (1); } catch (interruptedException e) {// toDo บล็อก catch block ที่สร้างขึ้นอัตโนมัติ E.PrintStackTrace (); -ตรวจสอบว่าเธรดเป็นเธรดพื้นหลังหรือไม่: เรียกใช้วิธี isDeamon () ของวัตถุเธรด
หมายเหตุ: เธรดหลักคือเธรดเบื้องหน้าโดยค่าเริ่มต้นเธรดลูกที่สร้างขึ้นในการสร้างเธรดเบื้องหน้าคือเธรดเบื้องหน้าโดยค่าเริ่มต้นและเธรดที่สร้างขึ้นในเธรดพื้นหลังคือเธรดพื้นหลังโดยค่าเริ่มต้น เมื่อเรียกใช้เมธอด setDeamon (จริง) เพื่อตั้งค่าเธรดเบื้องหน้าเป็นเธรดพื้นหลังจะต้องมีวิธีการเริ่มต้นก่อน () หลังจากเธรดเสียชีวิตเมื่อวันก่อนเมื่อวานนี้ JVM จะแจ้งให้เธรดพื้นหลังตาย แต่ต้องใช้เวลาในการรับคำแนะนำในการตอบกลับ
4. เปลี่ยนลำดับความสำคัญของเธรด/setPriority ():
แต่ละเธรดมีลำดับความสำคัญบางประการเมื่อดำเนินการและเธรดที่มีลำดับความสำคัญสูงมีโอกาสในการดำเนินการมากขึ้น แต่ละเธรดมีลำดับความสำคัญเช่นเดียวกับเธรดที่สร้างขึ้น เธรดหลักมีลำดับความสำคัญปกติตามค่าเริ่มต้น
ตั้งค่าลำดับความสำคัญของเธรด: setPriority (int priorityLevel) ช่วงพารามิเตอร์ prioritylevel อยู่ระหว่าง 1-10 และค่าคงที่สามค่าคงที่ที่ใช้กันทั่วไปมีดังนี้:
max_priority: 10
min_priority: 1
norm_priority: 5
รับลำดับความสำคัญของเธรด: getPriority ()
หมายเหตุ: วัตถุเธรดที่มีลำดับความสำคัญของเธรดที่สูงขึ้นหมายความว่าเธรดนี้มีโอกาสในการดำเนินการมากกว่าการดำเนินการลำดับความสำคัญ
Public Class Threadtest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {เธรด MyThread = new MyThread (); สำหรับ (int i = 0; i <100; i ++) {system.out.println ("เธรดหลัก i ="+i); if (i == 20) {mythread.setPriority (thread.max_priority); mythread.start (); }}}}} คลาส MyThread ขยายเธรด {โมฆะสาธารณะ run () {สำหรับ (int i = 0; i <100; i ++) {system.out.println ("i ="+i); -5. ข้อตกลงเธรด: ผลผลิต ()
บทบาทพื้นฐานของผลผลิต () ได้รับการกล่าวถึงในโพสต์บล็อกก่อนหน้า ในเวลาเดียวกันวิธีการให้ผลผลิต () ยังเกี่ยวข้องกับลำดับความสำคัญของเธรด เมื่อเธรดเรียกเมธอด eiled () เพื่อสลับจากสถานะการทำงานไปยังสถานะพร้อม CPU จะเลือกเธรดที่มีลำดับความสำคัญเท่ากันหรือลำดับความสำคัญสูงกว่าเป็นเธรดจากคิวเธรดสถานะพร้อมเพื่อดำเนินการ
Public Class Threadtest {โมฆะสาธารณะคงที่หลัก (String [] args) {เธรด MyThread1 = New MyThread1 (); เธรด MyThread2 = ใหม่ mythread2 (); mythread1.setPriority (thread.max_priority); mythread2.setPriority (thread.min_priority); สำหรับ (int i = 0; i <100; i ++) {system.out.println ("เธรดหลัก i ="+i); if (i == 20) {mythread1.start (); Mythread2.start (); Thread.yield (); }}}}} คลาส mythread1 ขยายเธรด {โมฆะสาธารณะเรียกใช้ () {สำหรับ (int i = 0; i <100; i ++) {system.out.println ("Mythread 1 - i ="+i); }}} คลาส mythread2 ขยายเธรด {public void run () {สำหรับ (int i = 0; i <100; i ++) {system.out.println ("Mythread 2 - i ="+i); -ชุดของบทความ:
คำอธิบายของอินสแตนซ์หลายเธรด Java (i)
คำอธิบายโดยละเอียดเกี่ยวกับอินสแตนซ์แบบมัลติเธรด Java (II)
คำอธิบายโดยละเอียดเกี่ยวกับอินสแตนซ์แบบมัลติเธรด Java (iii)