คลาสเธรด Java ยังเป็นคลาสวัตถุและอินสแตนซ์ของมันได้รับการสืบทอดมาจาก java.lang.thread หรือคลาสย่อย คุณสามารถสร้างเธรดใน Java ด้วยวิธีต่อไปนี้ การดำเนินการเธรดสามารถเรียกใช้เมธอด Start () ของเธรด:
ด้ายเหยียบ = เธรดใหม่ ();
thread.start ();
ในตัวอย่างด้านบนเราไม่ได้เขียนรหัสที่เรียกใช้สำหรับเธรดดังนั้นเธรดจะสิ้นสุดลงหลังจากเรียกเมธอด
มีสองวิธีในการเขียนโค้ดที่ดำเนินการเมื่อเธรดรัน: หนึ่งคือการสร้างอินสแตนซ์ของคลาสย่อยของเธรดและแทนที่วิธีการเรียกใช้และที่สองคือการใช้อินเตอร์เฟส runnable เมื่อสร้างคลาส ต่อไปเราจะอธิบายรายละเอียดทั้งสองวิธีนี้:
สร้างคลาสย่อยของเธรด
สร้างอินสแตนซ์ของคลาสย่อยเธรดและแทนที่วิธีการเรียกใช้ วิธีการเรียกใช้จะถูกดำเนินการหลังจากเรียกเมธอด start () ตัวอย่างของคลาสย่อยเธรดข้างต้นสามารถสร้างและเรียกใช้ในวิธีต่อไปนี้:
คลาสสาธารณะ MyThread ขยายเธรด {โมฆะสาธารณะ Run () {System.out.println ("MyThread Running"); }} MyThread MyThread = ใหม่ MyThread (); myTread.start ();เมื่อเธรดเริ่มต้นวิธีการเริ่มต้นจะกลับมาทันทีและจะไม่รอจนกว่าวิธีการเรียกใช้จะถูกดำเนินการก่อนที่จะกลับมา มันเหมือนกับวิธีการเรียกใช้จะถูกดำเนินการใน CPU อื่น เมื่อใช้วิธีการเรียกใช้งานสตริงการทำงานของ MyThread จะถูกพิมพ์
นอกจากนี้คุณยังสามารถสร้างคลาสย่อยที่ไม่ระบุชื่อของเธรดดังนี้:
เธรด = ใหม่เธรด () {โมฆะสาธารณะเรียกใช้ () {system.out.println ("เธรดรัน"); }}; thread.start ();เมื่อวิธีการเรียกใช้ของเธรดใหม่ถูกดำเนินการคอมพิวเตอร์จะพิมพ์สตริง "เธรดรัน"
การใช้อินเทอร์เฟซ Runnable
วิธีที่สองในการเขียนรหัสการดำเนินการเธรดคือการสร้างอินสแตนซ์ใหม่ของคลาสที่ใช้อินเตอร์เฟส java.lang.runnable และวิธีการในอินสแตนซ์สามารถเรียกได้โดยเธรด ต่อไปนี้เป็นตัวอย่าง:
คลาสสาธารณะ myrunnable ดำเนินการ runnable {public void run () {system.out.println ("myrunnable running"); -เพื่อให้เธรดดำเนินการวิธีการเรียกใช้ () จำเป็นต้องผ่านวัตถุอินสแตนซ์ของ myrunnable ไปยังคอนสตรัคเตอร์ของคลาสเธรด ตัวอย่างมีดังนี้:
เธรดเธรด = เธรดใหม่ (ใหม่ myrunnable ());
thread.start ();
เมื่อเธรดทำงานมันจะเรียกวิธีการเรียกใช้ที่ใช้อินเตอร์เฟส Runnable "Myrunnable Running" จะถูกพิมพ์ในตัวอย่างข้างต้น
ในทำนองเดียวกันคุณสามารถสร้างคลาสที่ไม่ระบุชื่อที่ใช้อินเตอร์เฟสที่เรียกใช้ได้ดังที่แสดงด้านล่าง:
runnable myrunnable = new runnable () {public void run () {system.out.println ("runnable runnable"); }} เธรดเธรด = เธรดใหม่ (myrunnable); thread.start ();สร้างคลาสย่อยหรือใช้อินเทอร์เฟซที่เรียกใช้งานได้หรือไม่?
ไม่มีคำตอบที่ชัดเจนว่าสองวิธีใดที่ดีกว่าและพวกเขาสามารถตอบสนองความต้องการ ในความเห็นส่วนตัวของฉันฉันชอบที่จะใช้วิธีการเชื่อมต่อแบบ runnable เนื่องจากพูลเธรดสามารถจัดการเธรดที่ใช้งานอินเตอร์เฟส Runnable ได้อย่างมีประสิทธิภาพหากพูลเธรดเต็มเธรดใหม่จะเข้าคิวเพื่อดำเนินการจนกว่าพูลเธรดจะไม่ได้ใช้งาน และหากเธรดถูกนำไปใช้โดยการใช้คลาสย่อยของเธรดสิ่งนี้จะซับซ้อนขึ้นเล็กน้อย
บางครั้งเราจำเป็นต้องรวมสองวิธีในการใช้งานอินเตอร์เฟส runnable และ subclass ของเธรดในเวลาเดียวกัน ตัวอย่างเช่นอินสแตนซ์ที่ใช้คลาสย่อยของเธรดสามารถเรียกใช้หลายเธรดที่ใช้อินเตอร์เฟส Runnable แอปพลิเคชันทั่วไปคือพูลเธรด
ข้อผิดพลาดทั่วไป: การเรียกใช้วิธีการเรียกใช้ () แทนเมธอด start ()
ข้อผิดพลาดทั่วไปที่เกิดขึ้นโดยการสร้างและเรียกใช้เธรดคือการเรียกวิธีการ Run () ของเธรดแทนวิธีการเริ่มต้น () ดังที่แสดงด้านล่าง:
เธรด newThread = เธรดใหม่ (myrunnable ());
newThread.run (); // ควรเริ่มต้น ();
ตอนแรกคุณไม่รู้สึกผิดพลาดเพราะวิธีการเรียกใช้ () เรียกว่าตามที่คุณต้องการ อย่างไรก็ตามในความเป็นจริงวิธีการเรียกใช้ () ไม่ได้ดำเนินการโดยเธรดใหม่ที่เพิ่งสร้าง แต่ดำเนินการโดยเธรดปัจจุบันที่สร้างเธรดใหม่ นั่นคือมันถูกดำเนินการโดยเธรดที่เรียกใช้รหัสสองบรรทัดข้างต้น ในการทำให้เธรดใหม่ที่สร้างขึ้นจะดำเนินการวิธีการเรียกใช้ () วิธีการเริ่มต้นของเธรดใหม่จะต้องเรียก
ชื่อเธรด
เมื่อสร้างเธรดคุณสามารถให้ชื่อเธรดได้ มันช่วยให้เราแยกแยะเธรดที่แตกต่างกัน ตัวอย่างเช่น: หากมีหลายเธรดที่เขียนไปยัง System.out เราสามารถค้นหาได้อย่างง่ายดายว่าเธรดใดกำลังส่งออกผ่านชื่อเธรด ตัวอย่างมีดังนี้:
myrunnable runnable = new myrunnable (); เธรดเธรด = เธรดใหม่ (runnable, "เธรดใหม่"); thread.start (); system.out.println (thread.getName ());
ควรสังเกตว่าเนื่องจาก myrunnable ไม่ใช่คลาสย่อยของเธรดคลาส myrunnable ไม่มีวิธี getName () คุณสามารถรับการอ้างอิงถึงเธรดปัจจุบันด้วยวิธีต่อไปนี้:
thread.currentthread ();
String threadName = thread.currentThread (). getName ();
ตัวอย่างเธรดรหัส:
นี่คือตัวอย่างเล็ก ๆ ก่อนอื่นเอาต์พุตชื่อเธรดของวิธีการหลัก () เธรดนี้จัดสรรโดย JVM จากนั้นเปิด 10 เธรดและตั้งชื่อพวกเขา 1 ~ 10 แต่ละเธรดออกจากการส่งออกชื่อของตัวเอง
Public Class ThreadExample {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {system.out.println (thread.currentthread (). getName ()); สำหรับ (int i = 0; i <10; i ++) {เธรดใหม่ ("" + i) {โมฆะสาธารณะเรียกใช้ () {system.out.println ("เธรด:" + getName () + "กำลังเรียกใช้"); } }.เริ่ม(); -ควรสังเกตว่าถึงแม้จะมีคำสั่งซื้อเธรดเริ่มต้นขึ้นคำสั่งของการดำเนินการจะไม่ได้รับคำสั่ง กล่าวคือเธรด 1 ไม่จำเป็นต้องเป็นเธรดแรกที่จะส่งออกชื่อไปยังคอนโซล นี่เป็นเพราะเธรดจะถูกดำเนินการแบบขนานมากกว่าตามลำดับ JVM และระบบปฏิบัติการกำหนดลำดับการดำเนินการของเธรดและลำดับการเริ่มต้นของมันไม่จำเป็นต้องเหมือนกับของเธรด
ข้างต้นเป็นการรวบรวมข้อมูลที่สร้างโดยกระทู้ Java เราจะยังคงเพิ่มข้อมูลที่เกี่ยวข้องในอนาคต ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!