ในคำอธิบายที่เข้าใจง่าย Runnable ใน Java คืออะไร? [ปิด]


95

"runnable" ใน Java คืออะไรในแง่ของคนธรรมดา? ฉันเป็นนักเรียนเขียนโปรแกรม AP ในโรงเรียนมัธยมซึ่งได้รับมอบหมายให้ทำวิจัยหรือค้นหาว่า "runnable" จากผู้อื่น (เราเพิ่งเข้าสู่ OOP และยังไม่ได้แตะเธรด)


มีเพียงบรรทัดเดียวที่มีประโยชน์ในเอกสาร API: "สัญญาทั่วไปของการรันเมธอดคืออาจดำเนินการใด ๆ ก็ตาม"
Tom Hawtin - แทคไลน์

งานวิจัยที่น่าสนใจกว่านั้นคืออะไรคือ "หยุดได้" ใน Java ในแง่ของคนธรรมดา วันนี้ผู้สอนเป็นอย่างนั้น ...
Udo Klimaschewski

9
@UdoKlimaschewski - ผู้ชายคนนี้เป็นนักเรียนมัธยมปลายไม่ใช่นักศึกษาระดับปริญญาตรีหรือสูงกว่าปริญญาตรี ความคาดหวังของผู้สอนนี้สอดคล้องกับระดับของนักเรียน ... IMO อย่างไรก็ตามฉันยอมรับว่า "first ask on SO" ไม่ใช่เทคนิคการวิจัยที่เหมาะสมสำหรับผู้ที่อยู่ในระดับ OP
Stephen C

คำตอบ:


192

โดยทั่วไปแล้ว Runnable เป็นประเภทของคลาส (Runnable คืออินเทอร์เฟซ) ที่สามารถใส่ลงในเธรดโดยอธิบายถึงสิ่งที่เธรดควรทำ

ส่วนต่อประสานที่รันได้ต้องการของคลาสเพื่อใช้วิธีการrun()ดังนี้:

public class MyRunnableTask implements Runnable {
     public void run() {
         // do stuff here
     }
}

แล้วใช้มันดังนี้:

Thread t = new Thread(new MyRunnableTask());
t.start();

หากคุณไม่มีRunnableอินเทอร์เฟซคลาส Thread ซึ่งมีหน้าที่ในการเรียกใช้งานเนื้อหาของคุณในเธรดอื่นจะไม่มีสัญญาว่าจะหาrun()วิธีการในคลาสของคุณดังนั้นคุณอาจได้รับข้อผิดพลาด นั่นคือเหตุผลที่คุณต้องติดตั้งอินเทอร์เฟซ

ขั้นสูง: ประเภทไม่ระบุตัวตน

โปรดทราบว่าคุณไม่จำเป็นต้องกำหนดคลาสตามปกติคุณสามารถทำแบบอินไลน์ได้ทั้งหมด:

Thread t = new Thread(new Runnable() {
    public void run() {
        // stuff here
    }
});
t.start();

สิ่งนี้คล้ายกับข้างต้นเพียง แต่คุณไม่ได้สร้างคลาสที่มีชื่ออื่น


68
นี่เป็นคำตอบที่ยอดเยี่ยมที่หักล้างข้ออ้างทั้งหมดที่ว่าคำถาม "ไม่สามารถตอบได้อย่างสมเหตุสมผลในรูปแบบปัจจุบัน"
Russell Silva

1
ฉันรู้ว่ามันเป็นเวลานาน แต่ฉันมีคำถาม เธรดถูกรันเพียงครั้งเดียวหรือเพียงแค่ทำงานซ้ำไปซ้ำมาภายในโปรแกรมเมื่อฉันเริ่มเธรด?
gamo

5
เธรดถูกรันจนกว่าrunเมธอดจะเสร็จสิ้นจากนั้นเธรดจะถูกปิด ถ้าคุณต้องการให้เธรดทำงานซ้ำไปซ้ำมาให้วางลูปไว้ในrunเมธอด
opatut

2
หรือใช้ฟังก์ชัน Java 8 lambda:new Thread(() -> System.out.println("hello from other thread")).start();
Gabe

10

Runnable เป็นอินเทอร์เฟซที่กำหนดดังนี้:

interface Runnable {
    public void run();
}

หากต้องการสร้างคลาสที่ใช้เพียงกำหนดคลาสเป็น (public) class MyRunnable implements Runnable {

สามารถใช้งานได้โดยไม่ต้องสร้าง Thread ใหม่ โดยพื้นฐานแล้วเป็นอินเทอร์เฟซพื้นฐานของคุณด้วยวิธีการเดียวเรียกใช้ที่สามารถเรียกได้

หากคุณสร้างเธรดใหม่โดยใช้พารามิเตอร์รันได้มันจะเรียกใช้วิธีการรันในเธรดใหม่

นอกจากนี้ควรสังเกตด้วยว่าเธรดใช้งานRunnableได้และจะถูกเรียกใช้เมื่อเธรดใหม่ถูกสร้างขึ้น (ในเธรดใหม่) การใช้งานเริ่มต้นเพียงแค่เรียกสิ่งที่รันได้ที่คุณมอบให้ในตัวสร้างซึ่งเป็นเหตุผลที่คุณสามารถทำได้new Thread(someRunnable)โดยไม่ต้องแทนที่runวิธีการของเธรด


คุณกำลังบอกว่าโดยพื้นฐานแล้วไม่มีความแตกต่างระหว่างการสืบทอด Thread หรือการใช้งาน Runnable? Thread เมื่อใช้ Runnable จะใช้เป็น wrapper หรือไม่?
opatut

ฉันกำลังบอกว่าไม่มีความแตกต่างระหว่าง [การขยายเธรดและการแทนที่รัน] และ [การสร้างอินสแตนซ์ใหม่ของเธรดที่มีรันได้ที่มีวิธีการรันเหมือนกัน]
Alex Coleman

ใช่แล้ว แต่จริงๆแล้วไม่มีความแตกต่างทั้งประสิทธิภาพหรืออย่างอื่น?
opatut

3
@AlexColeman - มีขนาดใหญ่ความแตกต่าง หากคุณขยายThreadเธรดพูลเป็นเรื่องยากและหากคุณไม่ใช้เธรดพูลคุณจะต้องเสียค่าใช้จ่ายจำนวนมากในการสร้างเธรดใหม่ตลอดเวลา ในทางตรงกันข้ามการใช้งานRunnableหมายความว่าคุณสามารถใช้สิ่งต่างๆเช่นThreadPoolExecutorServiceหรือพูลเธรดของบุคคลที่สามได้อย่างง่ายดาย
Stephen C
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.