जावा में एक अलग थ्रेड के साथ एक विधि कैसे कॉल करें?


126

मान लीजिए कि मेरे पास एक तरीका है doWork()। मैं इसे एक अलग धागे (मुख्य धागा नहीं) से कैसे कह सकता हूं।


इस हाल के संबंधित प्रश्न पर कुछ उदाहरण दिए गए हैं
ग्रेग हेविगिल

stackoverflow.com/questions/36832094/… मेरे पास एक ऐसा ही मुद्दा है pls इसे सुलझाने में मेरी मदद करें
Sruthi Acg

आप अतुल्यकालिक कार्यों के लिए प्रतिक्रियाशील जावा ब्लॉग.danlew.net/2014/09/15/grokking-rxjava-part-1 पर एक नज़र डालना पसंद कर सकते हैं
नाथन दून

जवाबों:


138

एक वर्ग बनाएं जो Runnableइंटरफ़ेस को लागू करता है। जिस कोड को आप run()विधि में चलाना चाहते हैं, उसे डालें - यह वह विधि है जिसे आपको Runnableइंटरफ़ेस के अनुपालन के लिए लिखना होगा । अपने "मुख्य" धागे में, एक नया Threadवर्ग बनाएं , कंस्ट्रक्टर को आपकी एक आवृत्ति से गुजरते हुए Runnable, फिर उस start()पर कॉल करें । startJVM से कहता है कि नया धागा बनाने के लिए जादू करें, और फिर runउस नए धागे में अपनी विधि कहें ।

public class MyRunnable implements Runnable {

    private int var;

    public MyRunnable(int var) {
        this.var = var;
    }

    public void run() {
        // code in the other thread, can reference "var" variable
    }
}

public class MainThreadClass {
    public static void main(String args[]) {
        MyRunnable myRunnable = new MyRunnable(10);
        Thread t = new Thread(myRunnable)
        t.start();
    }    
}

पर एक नजर डालें जावा के संगामिति ट्यूटोरियल आरंभ करने के लिए।

यदि आपकी विधि को अक्सर कहा जा रहा है, तो यह हर बार एक नया धागा बनाने के लायक नहीं हो सकता है, क्योंकि यह एक महंगा ऑपरेशन है। संभवतः किसी प्रकार के थ्रेड पूल का उपयोग करना सबसे अच्छा होगा। पर एक नज़र डालें Future, Callable, Executorमें कक्षाएं java.util.concurrentपैकेज।


1
क्या होगा यदि कोई चर है जिसे आप पास करना चाहते हैं?
लुई राइस

8
run()विधि कोई पैरामीटर लगता है, इसलिए एक चर वहाँ से पारित नहीं कर सकते हैं। मेरा सुझाव है कि आप इसे कंस्ट्रक्टर में पास कर दें - मैं अपना उत्तर दिखाने के लिए संपादित करूँगा।
नोएल एम

1
क्या एक अलग धागे में 1 विधि को कॉल करने का एक छोटा तरीका है? मुझे इसका new Thread() { public void run() {myMethod();}}.start();तरीका पता है , क्या यह सबसे छोटा है?
स्टीवन रूज

क्या आप और MANN के उत्तर में अंतर बता सकते हैं?
आसिफ मुश्ताक

2
MANN का उत्तर अनाम कार्यान्वयन का उपयोग करता है Runnable- मेरा एक वर्ग है जो विस्तार करता है Runnable। और क्योंकि मैंने किया है कि मेरे पास अपना खुद का कंस्ट्रक्टर है जो राज्य को तात्कालिक वस्तु में बदल देता है।
नोएल एम

183
Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        // code goes here.
    }
});  
t1.start();

या

new Thread(new Runnable() {
     @Override
     public void run() {
          // code goes here.
     }
}).start();

या

new Thread(() -> {
    // code goes here.
}).start();

या

Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override
    public void run() {
        myCustomMethod();
    }
});

या

Executors.newCachedThreadPool().execute(new Runnable() {
    @Override
    public void run() {
        myCustomMethod();
    }
});

यह पूरी तरह से मेरे लिए काम कर रहा था। एक webservice चलाने की जरूरत है और पर्यवेक्षक पैटर्न का उपयोग करके समवर्ती रूप से प्रगति पट्टी को अपडेट करना है।
dpi

@ आशीष: कृपया समझाएं कि क्या और क्यों संपादित किया गया है?
MANN

1
@ आशीषअगरवाल: मुझे अजीब लगता है जब कोई लेखक की अनुमति के बिना ऐसा करता है!
MANN

@MANN आप समझा सकते हैं कि आप थ्रेड पैरामीटर में रन विधि का उपयोग क्यों करते हैं? कोई बेहतर प्रदर्शन?
आसिफ मुश्ताक

1
क्या हमें धागे को स्पष्ट रूप से समाप्त करने की आवश्यकता है? क्या थ्रेड को स्पष्ट रूप से समाप्त नहीं करके मेमोरी लीक बनाने का जोखिम है? या जब यह किया जाता है तो धागा समाप्त हो जाता है run()?
वेव

59

Java 8 में आप कोड की एक लाइन के साथ ऐसा कर सकते हैं।

यदि आपकी विधि कोई पैरामीटर नहीं लेती है, तो आप विधि संदर्भ का उपयोग कर सकते हैं:

new Thread(MyClass::doWork).start();

अन्यथा, आप विधि को लंबोदर अभिव्यक्ति में कह सकते हैं:

new Thread(() -> doWork(someParam)).start();

इस वापस लाने के लिए क्षमा करें, लेकिन वास्तव में क्या ->मतलब है?
काइल

1
वह लंबोदर एक्सप्रेशन बनाने के लिए प्रयुक्त वाक्य रचना है। अधिक जानकारी के लिए इन लिंक पर एक नज़र डालें: जावा में '->' क्या करता है? , और जावा ™ ट्यूटोरियल - लैम्ब्डा एक्सप्रेशंस
हारून कोहन

@AaronCohn महान सामान आदमी! क्या आप जावा में थ्रेड्स का कोई विकल्प जानते हैं? मैं पायथन दुनिया से आता हूं, जो हम Celery task queueअतुल्यकालिक सामान के लिए उपयोग करेंगे
CESCO

जावा में थ्रेड्स से निपटने के लिए उच्च स्तर के सार हैं , लेकिन शायद आप अक्का की तरह कुछ और देख रहे हैं ?
हारून कोहन

8

चीजों को कॉल करने के लिए एक और तेज़ विकल्प (जैसे कि डायलॉगबॉक्स और मैसेजबॉक्स और बिना थ्रेड के सुरक्षित तरीकों के लिए अलग थ्रेड बनाना) लांबा एक्सप्रेशन का उपयोग करना होगा

  new Thread(() -> {
                      "code here"
            }).start();

3

कुछ समय पहले, मैंने एक साधारण उपयोगिता वर्ग लिखा था जो JDK5 निष्पादक सेवा का उपयोग करता है और पृष्ठभूमि में विशिष्ट प्रक्रियाओं को निष्पादित करता है। चूंकि doWork () में आमतौर पर एक शून्य रिटर्न मान होता है, आप पृष्ठभूमि में इसे निष्पादित करने के लिए इस उपयोगिता वर्ग का उपयोग करना चाह सकते हैं।

इस लेख को देखें जहाँ मैंने इस उपयोगिता को प्रलेखित किया था।


6
Future और Callable आपके लिए इस तरह का काम करते हैं।
अमीर अफगानी

हां वे करते हैं। यहाँ विचार एक अतुल्यकालिक आवरण के पीछे इंटरफेस को अमूर्त करने के लिए है।
रजा कोल्लुरु

लिंक टूट गया है (404)।
पालक

3

RxJava 2.x के साथ इसे प्राप्त करने के लिए आप इसका उपयोग कर सकते हैं:

Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();

यह subscribeOn()विधि निर्दिष्ट करती है कि किस शेड्यूलर पर कार्रवाई चलनी है - RxJava में कई पूर्वनिर्धारित अनुसूचक हैं, जिनमें Schedulers.io()I / O संचालन के लिए एक थ्रेड पूल है, और Schedulers.computation()जो CPU गहन संचालन के लिए अभिप्रेत है।


3

यदि आप कम से कम जावा 8 का उपयोग कर रहे हैं, तो आप runAsyncक्लास कंप्लीटेबल फ़ॉइल से विधि का उपयोग कर सकते हैं

CompletableFuture.runAsync(() -> {...});

यदि आपको supplyAsyncइसके बजाय परिणाम उपयोग वापस करने की आवश्यकता है

CompletableFuture.supplyAsync(() -> 1);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.