บทช่วยสอน การเขียนโปรแกรม Java แบบมัลติเธรด ที่ดีที่สุดในปี 2024 ในบทช่วยสอนนี้ คุณสามารถเรียนรู้ วงจรชีวิตของเธรด,จัดลำดับความสำคัญของเธรด,สร้างหัวข้อ,เพื่อสร้างด้ายโดยใช้อินเตอร์เฟซ Runnable,เพื่อสร้างด้ายผ่านกระทู้มรดก,วิธีกระทู้,ด้ายแนวคิดที่สำคัญหลายประการ:,ใช้หลายหัวข้อ,
การเขียนโปรแกรม Java แบบมัลติเธรดที่จะให้การสนับสนุนในตัว โปรแกรมแบบมัลติเธรดมีสองคนหรือมากกว่าบางส่วนสามารถทำงานพร้อมกัน ส่วนหนึ่งของโปรแกรมแต่ละครั้งจะถูกเรียกว่าด้ายและแต่ละหัวข้อกำหนดเส้นทางที่แยกต่างหากจากการดำเนินการ
Multithreading เป็นรูปแบบพิเศษของแบบ multi-tasking multi-Threading แต่ใช้ค่าใช้จ่ายทรัพยากรที่มีขนาดเล็ก
อีกคำที่ถูกกำหนดไว้ในที่นี้และด้ายที่เกี่ยวข้อง - กระบวนการ: กระบวนการรวมถึงระบบปฏิบัติการจัดสรรพื้นที่หน่วยความจำที่มีหนึ่งหรือมากกว่าหนึ่งหัวข้อ หัวข้อแยกไม่สามารถอยู่ได้นั้นจะต้องเป็นส่วนหนึ่งของกระบวนการ กระบวนการได้รับการทำงานจะสิ้นสุดในทุกที่ไม่ได้รอจนกระทั่งหลังจากการสิ้นสุดของด้ายไปทำงาน
Multithreading สามารถตอบสนองความโปรแกรมเมอร์เขียนโปรแกรมที่มีประสิทธิภาพที่จะไปถึงจุดประสงค์ในการใช้งาน CPU เต็ม
ด้ายผ่านทุกขั้นตอนของวงจรชีวิตของมัน รูปต่อไปนี้แสดงให้เห็นวงจรชีวิตที่สมบูรณ์ของด้าย
หลังจากใช้คำหลักใหม่และชั้นกระทู้หรือ subclass การสร้างวัตถุด้ายวัตถุด้ายอยู่ในสภาพใหม่ มันยังคงอยู่ในสภาพนี้จนกว่าจะมีการเริ่มต้นโครงการ () หัวข้อนี้
เมื่อวัตถุด้ายโทรเริ่มต้น () method, ด้ายเข้าสู่สถานะพร้อม ด้ายพร้อมในคิวพร้อมที่จะรอให้ด้าย JVM การตั้งเวลาการจัดตารางเวลา
ถ้าด้ายที่ได้รับสถานะพร้อมของทรัพยากรของ CPU คุณสามารถดำเนินการ run () ด้ายจะทำงานในขณะนี้ ด้ายทำงานที่ซับซ้อนมากที่สุดก็จะกลายเป็นรัฐที่ถูกบล็อกสถานะพร้อมและสถานะของการเสียชีวิต
ถ้าด้ายจะถูกดำเนินการหลังจากการนอนหลับ (Sleep) suspend (แฮงค์) และวิธีการอื่น ๆ , การสูญเสียทรัพยากรครอบครองด้ายเข้าสู่รัฐที่ถูกบล็อกจากการทำงาน หลังจากที่เวลาการนอนหลับที่มีมารับอุปกรณ์หรือทรัพยากรที่จะกลับเข้าสู่สถานะพร้อม
เมื่อรัฐด้ายทำงานของงานหรือเงื่อนไขอื่น ๆ การเลิกจ้างเกิดขึ้นด้ายจะเปลี่ยนเป็นรัฐที่สิ้นสุด
แต่ละหัวข้อ Java มีลำดับความสำคัญซึ่งจะช่วยให้ตรวจสอบระบบปฏิบัติการด้ายเพื่อการตั้งเวลา
ลำดับความสำคัญด้าย Java เป็นจำนวนเต็มซึ่งมีตั้งแต่ 1 (Thread.MIN_PRIORITY) - 10 (Thread.MAX_PRIORITY)
โดยค่าเริ่มต้นแต่ละหัวข้อที่ได้รับมอบหมาย NORM_PRIORITY ลำดับความสำคัญ (5)
หัวข้อที่มีความสำคัญสูงเป็นสิ่งสำคัญมากในการเขียนโปรแกรมและควรจัดสรรทรัพยากรประมวลผลก่อนหัวข้อสำคัญต่ำ อย่างไรก็ตามการสั่งซื้อไม่ได้รับประกันความสำคัญด้ายด้ายของการดำเนินการและเป็นมากขึ้นอยู่กับอินเทอร์เน็ต
Java ให้สองวิธีการสร้างหัวข้อ:
สร้างหัวข้อวิธีที่ง่ายที่สุดคือการสร้างคลาสที่ใช้อินเตอร์เฟซ Runnable
เพื่อให้บรรลุ Runnable ชั้นเท่านั้นจำเป็นต้องดำเนินการเรียกใช้วิธีการโทร () คำสั่งต่อไป
public void run()
คุณสามารถแทนที่วิธีการนี้ก็เป็นสิ่งสำคัญที่จะเข้าใจการทำงาน () สามารถโทรหาวิธีการอื่น ๆ ที่ใช้ในการเรียนอื่น ๆ และประกาศตัวแปรเช่นเดียวกับหัวข้อหลัก
หลังจากที่สร้างชั้นเรียนดำเนิน interface Runnable คุณสามารถยกตัวอย่างวัตถุในชั้นเรียนด้าย
กระทู้กำหนดหลายก่อสร้างที่ติดตามนี้เรามักจะใช้:
Thread(Runnable threadOb,String threadName);
นี่ threadOb เป็นตัวอย่างของคลาสที่ใช้อินเตอร์เฟซ Runnable และ threadName ระบุชื่อใหม่ของด้าย
หลังจากที่หัวข้อใหม่ถูกสร้างขึ้นคุณโทรเริ่มต้น () วิธีการของมันจะทำงาน
void start();
นี่คือตัวอย่างของการสร้างด้ายและเริ่มต้นการดำเนินการ:
// 创建一个新的线程 class NewThread implements Runnable { Thread t; NewThread() { // 创建第二个新线程 t = new Thread(this, "Demo Thread"); System.out.println("Child thread: " + t); t.start(); // 开始线程 } // 第二个线程入口 public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Child Thread: " + i); // 暂停线程 Thread.sleep(50); } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); } } public class ThreadDemo { public static void main(String args[]) { new NewThread(); // 创建一个新线程 try { for(int i = 5; i > 0; i--) { System.out.println("Main Thread: " + i); Thread.sleep(100); } } catch (InterruptedException e) { System.out.println("Main thread interrupted."); } System.out.println("Main thread exiting."); } }
รวบรวมโปรแกรมข้างต้นทำงานดังต่อไปนี้:
Child thread: Thread[Demo Thread,5,main] Main Thread: 5 Child Thread: 5 Child Thread: 4 Main Thread: 4 Child Thread: 3 Child Thread: 2 Main Thread: 3 Child Thread: 1 Exiting child thread. Main Thread: 2 Main Thread: 1 Main thread exiting.
วิธีที่สองเพื่อสร้างหัวข้อคือการสร้างคลาสใหม่ที่สืบทอดคลาสกระทู้แล้วสร้างตัวอย่างของชั้นเรียนได้
รับค่าเรียนจะต้องแทนที่เมธอด run () ซึ่งเป็นจุดเริ่มต้นสำหรับหัวข้อใหม่ นอกจากนี้ยังต้องโทรเริ่มต้น () วิธีการดำเนินการ
// 通过继承 Thread 创建线程 class NewThread extends Thread { NewThread() { // 创建第二个新线程 super("Demo Thread"); System.out.println("Child thread: " + this); start(); // 开始线程 } // 第二个线程入口 public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Child Thread: " + i); // 让线程休眠一会 Thread.sleep(50); } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); } } public class ExtendThread { public static void main(String args[]) { new NewThread(); // 创建一个新线程 try { for(int i = 5; i > 0; i--) { System.out.println("Main Thread: " + i); Thread.sleep(100); } } catch (InterruptedException e) { System.out.println("Main thread interrupted."); } System.out.println("Main thread exiting."); } }
รวบรวมโปรแกรมข้างต้นทำงานดังต่อไปนี้:
Child thread: Thread[Demo Thread,5,main] Main Thread: 5 Child Thread: 5 Child Thread: 4 Main Thread: 4 Child Thread: 3 Child Thread: 2 Main Thread: 3 Child Thread: 1 Exiting child thread. Main Thread: 2 Main Thread: 1 Main thread exiting.
ตารางต่อไปนี้แสดงระดับกระทู้บางวิธีที่สำคัญ:
เลขที่ | วิธีการรายละเอียด |
---|---|
1 | เริ่มต้นโมฆะสาธารณะ () ให้หัวข้อนี้จะเริ่มต้นการดำเนินการ; โปรแกรม Java Virtual Machine เรียกวิธีการทำงานของหัวข้อนี้ |
2 | ประชาชนทำงานเป็นโมฆะ () ถ้ากระทู้นี้ถูกสร้างขึ้นโดยใช้แยกวัตถุวิ่ง Runnable แล้วเรียกวิธีการทำงานของวัตถุ Runnable; วิธีการนี้มิฉะนั้นจะไม่ทำอะไรเลยและผลตอบแทน |
3 | สุดท้ายประชาชนเป็นโมฆะ setName (ชื่อ String) เปลี่ยนชื่อของหัวข้อนี้เพื่อให้ชื่อพารามิเตอร์เดียวกัน |
4 | สุดท้ายประชาชนเป็นโมฆะ setPriority (int ลำดับความสำคัญ) เปลี่ยนลำดับความสำคัญด้าย |
5 | สุดท้ายประชาชนเป็นโมฆะ setDaemon boolean (ON) ทำเครื่องหมายหัวข้อนี้เป็นหัวข้อภูตหรือด้ายผู้ใช้ |
6 | โมฆะสาธารณะสุดท้ายเข้าร่วม (millisec ยาว) รอกระทู้นี้ให้สูงสุดของมิลลิวินาทีมิลลิวินาที |
7 | โมฆะสาธารณะขัดจังหวะ () ด้ายขัดจังหวะ |
8 | สุดท้ายประชาชน isAlive บูลีน () ทดสอบว่ากระทู้นี้มีการใช้งาน |
ทดสอบว่ากระทู้นี้มีการใช้งาน วิธีการดังกล่าวเรียกว่าวัตถุกระทู้ วิธีการต่อไปนี้เป็นวิธีการคงระดับของเธรด
เลขที่ | วิธีการรายละเอียด |
---|---|
1 | สาธารณะคงอัตราผลตอบแทนที่เป็นโมฆะ () ระงับวัตถุด้ายขณะนี้การดำเนินการและดำเนินการหัวข้ออื่น ๆ |
2 | ประชาชนเป็นโมฆะคงนอนหลับ (millisec ยาว) ภายในจำนวนที่ระบุของมิลลิวินาทีในขณะนี้การดำเนินการด้ายเพื่อการนอนหลับ (การดำเนินการหยุด) นี้จับเวลาระบบปฏิบัติการและ schedulers โดยความแม่นยำและความถูกต้องของ |
3 | สาธารณะคง holdsLock บูลีน (Object x) และถ้าหากเธรดปัจจุบันถือล็อคจอแสดงผลบนวัตถุที่ระบุก็จะส่งกลับจริง |
4 | ประชาชนกระทู้คง currentThread () ก็จะส่งกลับการอ้างอิงไปยังวัตถุด้ายขณะนี้การดำเนินการคือ |
5 | ประชาชนเป็นโมฆะคง dumpStack () เธรดปัจจุบันของสแต็คร่องรอยพิมพ์กระแสข้อผิดพลาดมาตรฐาน |
โปรแกรมต่อไปนี้แสดงให้เห็นถึงบางส่วนของวิธี ThreadClassDemo ชั้นกระทู้นี้:
// 文件名 : DisplayMessage.java // 通过实现 Runnable 接口创建线程 public class DisplayMessage implements Runnable { private String message; public DisplayMessage(String message) { this.message = message; } public void run() { while(true) { System.out.println(message); } } }
// 文件名 : GuessANumber.java // 通过继承 Thread 类创建线程 public class GuessANumber extends Thread { private int number; public GuessANumber(int number) { this.number = number; } public void run() { int counter = 0; int guess = 0; do { guess = (int) (Math.random() * 100 + 1); System.out.println(this.getName() + " guesses " + guess); counter++; }while(guess != number); System.out.println("** Correct! " + this.getName() + " in " + counter + " guesses.**"); } }
// 文件名 : ThreadClassDemo.java public class ThreadClassDemo { public static void main(String [] args) { Runnable hello = new DisplayMessage("Hello"); Thread thread1 = new Thread(hello); thread1.setDaemon(true); thread1.setName("hello"); System.out.println("Starting hello threadth."); thread1.start(); Runnable bye = new DisplayMessage("Goodbye"); Thread thread2 = new Thread(bye); thread2.setPriority(Thread.MIN_PRIORITY); thread2.setDaemon(true); System.out.println("Starting goodbye threadth."); thread2.start(); System.out.println("Starting thread3th."); Thread thread3 = new GuessANumber(27); thread3.start(); try { thread3.join(); }catch(InterruptedException e) { System.out.println("Thread interrupted."); } System.out.println("Starting thread4th."); Thread thread4 = new GuessANumber(75); thread4.start(); System.out.println("main() is endingth."); } }
ผลมีดังนี้ผลของแต่ละการทำงานจะไม่เหมือนกัน
Starting hello threadth. Starting goodbye threadth. Hello Hello Hello Hello Hello Hello Hello Hello Hello Thread-2 guesses 27 Hello ** Correct! Thread-2 in 102 guesses.** Hello Starting thread4th. Hello Hello thththththremaining result produced.
เมื่อ multithreaded การเขียนโปรแกรมที่คุณจำเป็นต้องเข้าใจแนวคิดต่อไปนี้:
กุญแจสำคัญในการใช้งานที่มีประสิทธิภาพของโปรแกรมแบบมัลติเธรดมีการดำเนินการพร้อมกันเป็นที่เข้าใจกันมากกว่าการดำเนินการแบบอนุกรม ตัวอย่างเช่นโปรแกรมที่มีสองระบบย่อยต้องดำเนินควบคู่กันไปคราวนี้คุณจะต้องใช้ประโยชน์จากการเขียนโปรแกรมแบบมัลติเธรด
ผ่านการใช้งานหลายหัวข้อที่คุณสามารถเขียนโปรแกรมที่มีประสิทธิภาพมาก อย่างไรก็ตามโปรดทราบว่าหากคุณสร้างหัวข้อมากเกินไปประสิทธิภาพของการทำงานของโปรแกรมจะลดลงจริงมากกว่าที่เพิ่มขึ้น
โปรดจำไว้ว่าบริบทสลับค่าใช้จ่ายนอกจากนี้ยังเป็นสิ่งสำคัญมากถ้าคุณสร้างหัวข้อมากเกินไปเวลา CPU ที่ใช้ในบริบทเปลี่ยนเวลาของการทำงานของโปรแกรมจะมีมากขึ้น!