บทช่วยสอน การเขียนโปรแกรม Java แบบมัลติเธรด ที่ดีที่สุดในปี 2024 ในบทช่วยสอนนี้ คุณสามารถเรียนรู้ วงจรชีวิตของเธรด,จัดลำดับความสำคัญของเธรด,สร้างหัวข้อ,เพื่อสร้างด้ายโดยใช้อินเตอร์เฟซ Runnable,เพื่อสร้างด้ายผ่านกระทู้มรดก,วิธีกระทู้,ด้ายแนวคิดที่สำคัญหลายประการ:,ใช้หลายหัวข้อ,

การเขียนโปรแกรม Java แบบมัลติเธรด

การเขียนโปรแกรม Java แบบมัลติเธรดที่จะให้การสนับสนุนในตัว โปรแกรมแบบมัลติเธรดมีสองคนหรือมากกว่าบางส่วนสามารถทำงานพร้อมกัน ส่วนหนึ่งของโปรแกรมแต่ละครั้งจะถูกเรียกว่าด้ายและแต่ละหัวข้อกำหนดเส้นทางที่แยกต่างหากจากการดำเนินการ

Multithreading เป็นรูปแบบพิเศษของแบบ multi-tasking multi-Threading แต่ใช้ค่าใช้จ่ายทรัพยากรที่มีขนาดเล็ก

อีกคำที่ถูกกำหนดไว้ในที่นี้และด้ายที่เกี่ยวข้อง - กระบวนการ: กระบวนการรวมถึงระบบปฏิบัติการจัดสรรพื้นที่หน่วยความจำที่มีหนึ่งหรือมากกว่าหนึ่งหัวข้อ หัวข้อแยกไม่สามารถอยู่ได้นั้นจะต้องเป็นส่วนหนึ่งของกระบวนการ กระบวนการได้รับการทำงานจะสิ้นสุดในทุกที่ไม่ได้รอจนกระทั่งหลังจากการสิ้นสุดของด้ายไปทำงาน

Multithreading สามารถตอบสนองความโปรแกรมเมอร์เขียนโปรแกรมที่มีประสิทธิภาพที่จะไปถึงจุดประสงค์ในการใช้งาน CPU เต็ม


วงจรชีวิตของเธรด

ด้ายผ่านทุกขั้นตอนของวงจรชีวิตของมัน รูปต่อไปนี้แสดงให้เห็นวงจรชีวิตที่สมบูรณ์ของด้าย

java_thread

  • สถานะใหม่:

    หลังจากใช้คำหลักใหม่และชั้นกระทู้หรือ subclass การสร้างวัตถุด้ายวัตถุด้ายอยู่ในสภาพใหม่ มันยังคงอยู่ในสภาพนี้จนกว่าจะมีการเริ่มต้นโครงการ () หัวข้อนี้

  • รัฐพร้อม:

    เมื่อวัตถุด้ายโทรเริ่มต้น () method, ด้ายเข้าสู่สถานะพร้อม ด้ายพร้อมในคิวพร้อมที่จะรอให้ด้าย JVM การตั้งเวลาการจัดตารางเวลา

  • สถานะการทำงาน:

    ถ้าด้ายที่ได้รับสถานะพร้อมของทรัพยากรของ CPU คุณสามารถดำเนินการ run () ด้ายจะทำงานในขณะนี้ ด้ายทำงานที่ซับซ้อนมากที่สุดก็จะกลายเป็นรัฐที่ถูกบล็อกสถานะพร้อมและสถานะของการเสียชีวิต

  • รัฐที่ถูกบล็อก:

    ถ้าด้ายจะถูกดำเนินการหลังจากการนอนหลับ (Sleep) suspend (แฮงค์) และวิธีการอื่น ๆ , การสูญเสียทรัพยากรครอบครองด้ายเข้าสู่รัฐที่ถูกบล็อกจากการทำงาน หลังจากที่เวลาการนอนหลับที่มีมารับอุปกรณ์หรือทรัพยากรที่จะกลับเข้าสู่สถานะพร้อม

  • สถานะความตาย:

    เมื่อรัฐด้ายทำงานของงานหรือเงื่อนไขอื่น ๆ การเลิกจ้างเกิดขึ้นด้ายจะเปลี่ยนเป็นรัฐที่สิ้นสุด


จัดลำดับความสำคัญของเธรด

แต่ละหัวข้อ Java มีลำดับความสำคัญซึ่งจะช่วยให้ตรวจสอบระบบปฏิบัติการด้ายเพื่อการตั้งเวลา

ลำดับความสำคัญด้าย Java เป็นจำนวนเต็มซึ่งมีตั้งแต่ 1 (Thread.MIN_PRIORITY) - 10 (Thread.MAX_PRIORITY)

โดยค่าเริ่มต้นแต่ละหัวข้อที่ได้รับมอบหมาย NORM_PRIORITY ลำดับความสำคัญ (5)

หัวข้อที่มีความสำคัญสูงเป็นสิ่งสำคัญมากในการเขียนโปรแกรมและควรจัดสรรทรัพยากรประมวลผลก่อนหัวข้อสำคัญต่ำ อย่างไรก็ตามการสั่งซื้อไม่ได้รับประกันความสำคัญด้ายด้ายของการดำเนินการและเป็นมากขึ้นอยู่กับอินเทอร์เน็ต


สร้างหัวข้อ

Java ให้สองวิธีการสร้างหัวข้อ:

  • Runable โดยการใช้อินเตอร์เฟซ;
  • ผ่าน Class กระทู้มรดกของตัวเอง

เพื่อสร้างด้ายโดยใช้อินเตอร์เฟซ Runnable

สร้างหัวข้อวิธีที่ง่ายที่สุดคือการสร้างคลาสที่ใช้อินเตอร์เฟซ 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 ที่ใช้ในบริบทเปลี่ยนเวลาของการทำงานของโปรแกรมจะมีมากขึ้น!

การเขียนโปรแกรม Java แบบมัลติเธรด
10/30