ทุกคนที่นี่ดูเหมือนจะคิดว่าการใช้ Runnable เป็นวิธีที่จะไปและฉันไม่เห็นด้วยกับพวกเขาจริงๆ แต่ก็มีกรณีที่จะขยายเธรดในความคิดของฉันในความเป็นจริงคุณได้แสดงให้เห็นในรหัสของคุณ
หากคุณใช้ Runnable คลาสที่ใช้ Runnable จะไม่สามารถควบคุมชื่อเธรดได้มันเป็นรหัสเรียกที่สามารถตั้งชื่อเธรดได้ดังนี้
new Thread(myRunnable,"WhateverNameiFeelLike");
แต่ถ้าคุณขยายเธรดคุณจะต้องจัดการสิ่งนี้ภายในคลาสเอง (เช่นเดียวกับในตัวอย่างของคุณคุณตั้งชื่อเธรด 'ThreadB') ในกรณีนี้คุณ:
A) อาจให้ชื่อที่มีประโยชน์มากขึ้นสำหรับการดีบัก
B) กำลังบังคับให้ชื่อนั้นใช้สำหรับทุกอินสแตนซ์ของคลาสนั้น (เว้นแต่คุณจะเพิกเฉยต่อความจริงที่ว่ามันเป็นเธรดและทำข้างบนด้วยราวกับว่าเป็น Runnable แต่เรากำลังพูดถึงการประชุมที่นี่ในกรณีใด ๆ ไม่สนใจความเป็นไปได้ที่ฉันรู้สึก)
ตัวอย่างเช่นคุณอาจใช้การติดตามสแต็กของการสร้างและใช้เป็นชื่อเธรด สิ่งนี้อาจดูแปลก แต่ขึ้นอยู่กับว่าโค้ดของคุณมีโครงสร้างแบบใดมีประโยชน์มากสำหรับการดีบัก
สิ่งนี้อาจดูเหมือนเล็ก แต่ที่คุณมีแอปพลิเคชันที่ซับซ้อนมากที่มีเธรดจำนวนมากและสิ่งที่ 'หยุด' ในทันใดทั้งหมด (ด้วยเหตุผลของการหยุดชะงักหรืออาจเป็นเพราะข้อบกพร่องในโปรโตคอลเครือข่ายซึ่งจะน้อยกว่า ชัดเจน - หรือเหตุผลที่ไม่มีที่สิ้นสุดอื่น ๆ ) จากนั้นรับสแต็กการถ่ายโอนข้อมูลจาก Java โดยที่เธรดทั้งหมดเรียกว่า 'Thread-1', 'Thread-2', 'Thread-3' ไม่ได้มีประโยชน์เสมอไป (ขึ้นอยู่กับว่าเธรดของคุณเป็นอย่างไร มีโครงสร้างและไม่ว่าคุณจะสามารถบอกได้ว่ามีประโยชน์เพียงใดซึ่งเป็นเพียงแค่การติดตามสแต็กของพวกเขา - เป็นไปไม่ได้เสมอไปถ้าคุณใช้กลุ่มของหลายเธรดทั้งหมดที่ใช้รหัสเดียวกัน)
ต้องบอกว่าคุณสามารถทำข้างต้นได้ด้วยวิธีทั่วไปโดยการสร้างส่วนขยายของคลาสเธรดซึ่งตั้งชื่อให้เป็นสแต็กการติดตามของการเรียกใช้การสร้างแล้วใช้กับการใช้งาน Runnable ของคุณแทนคลาส Java Thread มาตรฐาน (ดูด้านล่าง) แต่นอกเหนือจากการติดตามสแต็กอาจมีข้อมูลเฉพาะบริบทเพิ่มเติมที่จะเป็นประโยชน์ในชื่อเธรดสำหรับการดีบัก (การอ้างอิงถึงหนึ่งในหลาย ๆ คิวหรือซ็อกเก็ตมันสามารถประมวลผลตัวอย่างเช่นในกรณีที่คุณอาจต้องการ ขยาย Thread โดยเฉพาะสำหรับกรณีนั้นเพื่อให้คุณสามารถให้คอมไพเลอร์บังคับให้คุณ (หรือผู้อื่นที่ใช้ไลบรารีของคุณ) ส่งผ่านข้อมูลบางอย่าง (เช่นคิว / ซ็อกเก็ตที่มีปัญหา) เพื่อใช้ในชื่อ)
นี่คือตัวอย่างของเธรดทั่วไปที่มีการติดตามการเรียกสแต็กเป็นชื่อ:
public class DebuggableThread extends Thread {
private static String getStackTrace(String name) {
Throwable t= new Throwable("DebuggableThread-"+name);
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
t.printStackTrace(ps);
return os.toString();
}
public DebuggableThread(String name) {
super(getStackTrace(name));
}
public static void main(String[] args) throws Exception {
System.out.println(new Thread());
System.out.println(new DebuggableThread("MainTest"));
}
}
และนี่คือตัวอย่างของเอาต์พุตเปรียบเทียบชื่อทั้งสอง:
Thread[Thread-1,5,main]
Thread[java.lang.Throwable: DebuggableThread-MainTest
at DebuggableThread.getStackTrace(DebuggableThread.java:6)
at DebuggableThread.<init>(DebuggableThread.java:14)
at DebuggableThread.main(DebuggableThread.java:19)
,5,main]