บางครั้ง เราจำเป็นต้องขัดจังหวะการทำงานของเธรด ณ จุดเวลาที่กำหนด เช่น เธรดที่ตรวจสอบสถานะของเซ็นเซอร์ทุกๆ นาที เวลาที่เหลือเธรดไม่จำเป็นต้องทำอะไรเลย ในช่วงเวลานี้ เธรดไม่จำเป็นต้องใช้ทรัพยากรใดๆ ของคอมพิวเตอร์ หลังจากช่วงเวลานี้ผ่านไป และเมื่อเครื่องเสมือน Java กำหนดเวลาเธรด เธรดจะยังคงดำเนินการต่อไป เมื่อต้องการทำเช่นนี้ คุณสามารถใช้เมธอด sleep() ของคลาส Thread ได้ วิธีนี้จะชะลอการดำเนินการของเธรดโดยการสลีป และพารามิเตอร์ชนิดจำนวนเต็มระบุจำนวนมิลลิวินาทีที่จะสลีป เมื่อเรียกใช้เมธอด sleep() และเวลาพักเครื่องสิ้นสุดลง เครื่องเสมือน Java จะจัดสรรเวลาการทำงานของ CPU ให้กับเธรด และเธรดจะดำเนินการต่อไป
อีกวิธีหนึ่งในการใช้เมธอด sleep() คือผ่านองค์ประกอบของประเภทการแจงนับ TimeUnit วิธีการนี้ใช้วิธี sleep() ของ Thread เพื่อทำให้ thread sleep ปัจจุบันสามารถยอมรับหน่วยเวลาที่ระบุเป็นพารามิเตอร์และแปลงเป็นจำนวนมิลลิวินาทีที่สอดคล้องกัน
ในส่วนนี้เราจะพัฒนาโปรแกรมที่ใช้เมธอด sleep() เพื่อพิมพ์เวลาปัจจุบันทุกวินาที
รู้ว่ามัน
ทำตามขั้นตอนที่แสดงด้านล่างเพื่อใช้ตัวอย่างในส่วนนี้
1. สร้างคลาสชื่อ FileClock และใช้อินเทอร์เฟซ Runnable รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
FileClock คลาสสาธารณะใช้ Runnable {
2. นำเมธอด run() ไปใช้ รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
@แทนที่
โมฆะสาธารณะวิ่ง () {
3. เขียนวงวนที่วนซ้ำสิบครั้งในการสร้างวัตถุ Date และพิมพ์ไปยังคอนโซล จากนั้น เรียกเมธอด sleep() ผ่านคุณสมบัติ SECONDS ของ TimeUtil เพื่อชะลอการดำเนินการของเธรดเป็นเวลาหนึ่งวินาที ฉันคิดว่าวิธีการ sleep() จะทำให้เกิด InterruptedException ดังนั้นเราจึงจำเป็นต้องเขียนโค้ดเพิ่มอีกสองสามบรรทัดเพื่อตรวจจับข้อยกเว้น เมื่อเธรดอาจถูกขัดจังหวะ แนวทางปฏิบัติที่ดีที่สุดคือการปล่อยหรือปิดทรัพยากรที่ใช้ในเธรดเสมอ รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
สำหรับ (int i = 0; i <10; i++) {
System.out.printf("%s/n", วันที่ใหม่());
พยายาม {
TimeUnit.SECONDS.sleep(1);
} จับ (InterruptedException e) {
System.out.printf("FileClock ถูกขัดจังหวะ/n");
-
-
4. เรามีคลาสเธรดที่ใช้งานได้ดีอยู่แล้ว ตอนนี้ เรามาประยุกต์ใช้คลาสหลักกันดีกว่า สร้างคลาสชื่อ FileMain และใช้เมธอด main() รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
FileMain ระดับสาธารณะ {
โมฆะคงที่สาธารณะ main (String [] args) {
5. สร้างวัตถุ FileClock จากนั้นสร้างเธรดเพื่อดำเนินงาน จากนั้นให้เริ่มเธรด รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
นาฬิกา FileClock = FileClock ใหม่ ();
เธรดเธรด = เธรดใหม่ (นาฬิกา);
เธรด.เริ่มต้น();
6. ในเธรดหลัก เรียกเมธอด sleep() ผ่านคุณสมบัติ SECONDS ของ TimeUtil เพื่อรอห้าวินาที รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
พยายาม {
TimeUnit.SECONDS.sleep (5);
} จับ (InterruptedException e) {
e.printStackTrace();
-
7. ขัดจังหวะเธรด FileClock รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
เธรด.ขัดจังหวะ();
8. ดำเนินการตามตัวอย่างและตรวจสอบผลการดำเนินการ
รู้ว่าทำไม
เมื่อคุณรันโปรแกรมนี้ คุณจะพบว่าโปรแกรมพิมพ์ออบเจ็กต์วันที่ทุกวินาทีอย่างไร และเธรดถูกขัดจังหวะอย่างไร
เมื่อเรียกใช้เมธอด sleep() เธรดจะออกจาก CPU และหยุดการดำเนินการเป็นระยะเวลาหนึ่ง ในระหว่างนี้ เธรดไม่ต้องการ CPU อีกต่อไป ดังนั้น CPU จึงสามารถทำงานอื่นได้
เมื่อเธรดที่หลับถูกขัดจังหวะ InterruptedException จะถูกโยนทิ้งทันทีแทนที่จะรอจนกว่าการนอนหลับจะสิ้นสุดลง
ไม่มีวันสิ้นสุด
ใน Java concurrency API มีวิธีอื่นในการอนุญาตให้เธรดเลิกใช้งาน CPU นี่คือวิธีการ Yield() การเรียกวิธีนี้จะส่งข้อความไปยังเครื่องเสมือน Java โดยระบุว่าเธรดสามารถมอบ CPU ให้กับเธรดอื่นได้ เครื่องเสมือน Java ไม่รับประกันว่าจะตอบสนองต่อคำขอนี้ โดยปกติวิธีนี้จะใช้เฉพาะเมื่อทำการดีบักโปรแกรมเท่านั้น
ใช้หลักคำสอน
บทความนี้แปลมาจาก "Java 7 Concurrency Cookbook" (D Gua Ge ขโมยมาในชื่อ "Java7 Concurrency Example Collection") และใช้เป็นสื่อการเรียนรู้เท่านั้น ห้ามนำไปใช้เพื่อวัตถุประสงค์ทางการค้าใดๆ โดยไม่ได้รับอนุญาต
ความสำเร็จเล็กๆ น้อยๆ
โค้ดตัวอย่างเวอร์ชันสมบูรณ์ที่ใช้ในส่วนนี้
รหัสที่สมบูรณ์ของคลาส FileClock มีดังนี้:
แพ็คเกจ com.diguage.books.concurrencycookbook.chapter1.recipe5;
นำเข้า java.util.Date;
นำเข้า java.util.concurrent.TimeUnit;
-
* พิมพ์วันที่และเวลาปัจจุบันไปยังคอนโซลทุกวินาที
* วันที่: 18-09-2556
* เวลา: 23:11 น
-
FileClock คลาสสาธารณะใช้ Runnable {
@แทนที่
โมฆะสาธารณะวิ่ง () {
สำหรับ (int i = 0; i <10; i++) {
System.out.printf("%s/n", วันที่ใหม่());
พยายาม {
TimeUnit.SECONDS.sleep (1);
} จับ (InterruptedException e) {
System.out.printf("FileClock ถูกขัดจังหวะ/n");
-
-
-
รหัสที่สมบูรณ์ของคลาส FileMain
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ com.diguage.books.concurrencycookbook.chapter1.recipe5;
นำเข้า java.util.concurrent.TimeUnit;
-
* สาธิตการนอนหลับของเธรดและดำเนินการต่อ
* วันที่: 19-09-2556
* เวลา: 00:29 น
-
FileMain ระดับสาธารณะ {
โมฆะคงที่สาธารณะ main (String [] args) {
นาฬิกา FileClock = FileClock ใหม่ ();
เธรดเธรด = เธรดใหม่ (นาฬิกา);
เธรด.เริ่มต้น();
พยายาม {
TimeUnit.SECONDS.sleep (5);
} จับ (InterruptedException e) {
e.printStackTrace();
-
เธรด.ขัดจังหวะ();
-
-