1. เข้าร่วมกระทู้ :
ในระหว่างการดำเนินการเธรด บางครั้งคุณต้องการให้เธรดอื่นดำเนินการก่อน เช่น การแบ่งปัญหาใหญ่ออกเป็นปัญหาเล็กๆ จำนวนมาก การกำหนดเธรดให้กับปัญหาเล็กๆ แต่ละปัญหา แต่หลังจากประมวลผลปัญหาเล็กๆ ทั้งหมดแล้ว ให้เธรดหลักดำเนินการต่อไป ในขณะนี้ เราสามารถเรียกเมธอด join() ของเธรดอื่นๆ ในเธรดหลักเพื่อบล็อกเธรดที่เรียกได้ (ในที่นี้ คือ เธรดหลัก)
รหัสตัวอย่าง:
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ org.frzh.thread;
คลาสสาธารณะ JoinThread ขยายเธรด {
//จัดเตรียม Constructor แบบกำหนดพารามิเตอร์เพื่อตั้งชื่อเธรด
JoinThread สาธารณะ (ชื่อสตริง) {
ซุปเปอร์(ชื่อ);
-
โมฆะสาธารณะวิ่ง () {
สำหรับ (int i = 0; i < 100; i++) {
System.out.println(getName() + " " + i);
-
-
โมฆะคงที่สาธารณะ main (String [] args) {
//เริ่มเธรดย่อย
new JoinThread("กระทู้ใหม่").start();
สำหรับ (int i = 0; i < 100; i++) {
ถ้า (ฉัน == 20) {
JoinThread jt = new JoinThread("thread to be join");
jt.เริ่มต้น();
// เธรดหลักเรียกวิธีการรวมของเธรด jt จากนั้นเธรดหลักต้องรอให้ jt ดำเนินการเสร็จสิ้นก่อนจึงจะสามารถดำเนินการได้
พยายาม {
jt.เข้าร่วม();
} จับ (InterruptedException e) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
-
System.out.println(Thread.currentThread().getName() + " " +i);
-
-
-
เดิมทีมีเธรดสามชุด (สองเธรดย่อยและเธรดหลักหนึ่งเธรด) เมื่อ i=20 เธรดหลักจะถูกบล็อกและต้องรอจนกว่า "เธรดที่เข้าร่วม" จะถูกดำเนินการก่อนที่จะมีโอกาสดำเนินการ ดังนั้นจึงมี เป็นเพียงสองเธรดที่ดำเนินการหลังจากนั้น
วิธีการ join() สามรูปแบบที่โอเวอร์โหลด:
เข้าร่วม (): รอให้เธรดที่เข้าร่วมดำเนินการเสร็จสิ้น
เข้าร่วม (มิลลิวินาทียาว): เวลาที่ยาวที่สุดในการรอเธรดที่เข้าร่วมเพื่อดำเนินการคือมิลลิวินาที หลังจากนั้น แม้ว่าเธรดที่เข้าร่วมจะยังดำเนินการไม่เสร็จสิ้น แต่ก็จะไม่รออีกต่อไป
เข้าร่วม (มิลลิวินาทียาว, int nanos): เวลาสูงสุดในการรอให้เธรดที่เข้าร่วมดำเนินการคือมิลลิวินาที มิลลิวินาที + นาโนไมโครวินาที (วิธีนี้โดยทั่วไปไม่มีประโยชน์)
2: เธรดพื้นหลัง :
มีเธรดที่ทำงานอยู่เบื้องหลัง และหน้าที่ของเธรดคือให้บริการเธรดอื่นๆ เมื่อเธรดเบื้องหน้าทั้งหมดตาย เธรดพื้นหลังก็จะตายโดยอัตโนมัติ
รหัสตัวอย่าง:
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ org.frzh.thread;
DaemonThread คลาสสาธารณะขยายเธรด {
โมฆะสาธารณะวิ่ง () {
สำหรับ (int i = 0; i < 1,000; i++) {
System.out.println(getName() + " " +i);
-
-
โมฆะคงที่สาธารณะ main (String [] args) {
DaemonThread dt = DaemonThread ใหม่ ();
// ตั้งกระทู้นี้เป็นกระทู้พื้นหลัง
dt.setDaemon(จริง);
dt.start();
สำหรับ (int i = 0; i <10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
-
//เธรดเบื้องหน้าสิ้นสุด จากนั้นเธรดพื้นหลัง dt ก็จะสิ้นสุดเช่นกัน ดังนั้นจึงจะไม่ดำเนินการ 999
-
-
เธรดหลักมีค่าเริ่มต้นเป็นเธรดเบื้องหน้า เธรดย่อยที่สร้างโดยเธรดเบื้องหน้ามีค่าเริ่มต้นเป็นเธรดเบื้องหน้า และเธรดย่อยที่สร้างโดยเธรดพื้นหลังมีค่าเริ่มต้นเป็นเธรดพื้นหลัง
3. เธรดสลีป (สลีป):
วิธีการรวมก่อนหน้านี้คือการปล่อยให้เธรดที่เรียกรอให้เธรดที่เข้าร่วมดำเนินการเสร็จสิ้นก่อนที่จะดำเนินการต่อ ในขณะที่วิธี sleep() คือปล่อยให้เธรดที่เรียกบล็อกเป็นระยะเวลาหนึ่งก่อนที่จะเข้าสู่สถานะพร้อมอีกครั้งและรอที่จะเป็น กำหนดไว้ ดังนั้นจึงมักใช้เพื่อหยุดการทำงานของโปรแกรมชั่วคราว
รหัสตัวอย่าง:
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ org.frzh.thread;
นำเข้า java.util.Date;
SleepThread คลาสสาธารณะ{
โมฆะคงที่สาธารณะ main (String [] args) {
สำหรับ (int i = 0; i <10; i++) {
System.out.println("เวลาปัจจุบัน: " + วันที่ใหม่());
พยายาม {
เธรด.สลีป(1,000);
} จับ (InterruptedException e) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
-
-
-
วิธี sleep() โอเวอร์โหลดสองวิธี:
static void sleep (มิลลิวินาทียาว): ปล่อยให้เธรดปัจจุบันหยุดชั่วคราวเป็นมิลลิวินาทีและเข้าสู่สถานะการบล็อก วิธีการนี้ได้รับผลกระทบจากความแม่นยำและความแม่นยำของตัวจับเวลาระบบและตัวกำหนดเวลาเธรด
โมฆะสลีปแบบคงที่ (มิลลิวินาทียาว int nanos): หยุดมิลลิวินาที + นาโนไมโครวินาทีชั่วคราว และเข้าสู่สถานะการบล็อก นอกจากนี้ยังจะได้รับผลกระทบจากความแม่นยำและความแม่นยำของตัวจับเวลาระบบและตัวกำหนดเวลาเธรด โดยพื้นฐานแล้วไม่จำเป็น
4. ผลผลิต ด้าย :
วิธีการ Yield() ค่อนข้างคล้ายกับวิธี Sleep นอกจากนี้ยังสามารถหยุดเธรดที่กำลังทำงานอยู่ชั่วคราวได้ แต่จะไม่บล็อกเธรด แต่เพียงโอนไปยังสถานะพร้อม (โปรดทราบว่าไม่ใช่สถานะการบล็อก) เมธอด Yield() จะให้โอกาสในการดำเนินการเธรดที่มีลำดับความสำคัญเท่ากันหรือสูงกว่าเท่านั้น ดังนั้นเธรดอาจถูกกำหนดเวลาใหม่เพื่อดำเนินการต่อไปหลังจากเรียกใช้เมธอดนี้
รหัสตัวอย่าง:
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ org.frzh.thread;
YieldThread คลาสสาธารณะขยายเธรด {
YieldThread สาธารณะ () {
-
YieldThread สาธารณะ (ชื่อสตริง) {
ซุปเปอร์(ชื่อ);
-
โมฆะสาธารณะวิ่ง () {
สำหรับ (int i = 0; i < 100; i++) {
System.out.println(getName() + " " +i);
ถ้า (ฉัน == 20) {
// เธรดปัจจุบันให้ผล
เธรด.ผลผลิต();
-
-
-
โมฆะคงที่สาธารณะ main (String [] args) {
//เริ่มสองเธรดพร้อมกัน
YieldThread yt1 = YieldThread ใหม่ ("ขั้นสูง");
//กำหนดให้ yt1 เป็นลำดับความสำคัญสูงสุด
yt1.setPriority(เธรด.MAX_PRIORITY);
yt1.start();
YieldThread yt2 = YieldThread ใหม่ ("ระดับต่ำ");
yt2.setPriority(เธรด.MIN_PRIORITY);
yt2.start();
-
* หากไม่ได้ตั้งค่าลำดับความสำคัญสำหรับเธรด ลำดับความสำคัญของทั้งสองเธรดจะเหมือนกัน ดังนั้นทั้งสองเธรดจะดำเนินการสลับกัน และเมื่อมีการเรียกใช้ผลผลิต เธรดอื่นจะดำเนินการ
* อย่างไรก็ตาม หลังจากตั้งค่าลำดับความสำคัญข้างต้นสำหรับสองเธรดตามลำดับแล้ว การประมวลผลเธรดขั้นสูงจะเริ่มต้นขึ้น เมื่อ i=20 จะเรียกใช้ฟังก์ชัน Yield แต่เนื่องจากเมธอด Yield จะใช้งานได้เท่านั้น
* ให้โอกาสในการดำเนินการกับเธรดที่มีลำดับความสำคัญเท่ากันหรือสูงกว่า ดังนั้นเธรดระดับสูงจึงยังคงดำเนินการอยู่ในขณะนี้ และจะไม่มอบให้กับเธรดระดับต่ำ
-
-
-
5: เปลี่ยนลำดับความสำคัญของเธรด :
ซึ่งค่อนข้างง่าย เพียงเรียกเมธอดอินสแตนซ์ setPriority(int Priority) แต่ละเธรดมีค่าเริ่มต้นที่ลำดับความสำคัญเดียวกันกับเธรดหลัก และเธรดหลักมีค่าเริ่มต้นที่ลำดับความสำคัญปกติ (5) Java จัดเตรียมลำดับความสำคัญตั้งแต่ 1 ถึง 10 และคุณยังสามารถใช้ค่าคงที่คงที่สามค่าได้:
MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5
หมายเหตุ: แม้ว่า Java จะมีลำดับความสำคัญ 10 ลำดับความสำคัญ แต่ระบบที่แตกต่างกันก็รองรับลำดับความสำคัญที่แตกต่างกัน ดังนั้นพยายามหลีกเลี่ยงการใช้ตัวเลขระหว่าง 1 ถึง 10 โดยตรง และใช้ค่าคงที่คงที่เพื่อให้แน่ใจว่าสามารถพกพาได้ดี