2013-04-28 9 views
22

यह एक सामान्य जावा प्रश्न है और एंड्रॉइड पहले नहीं!माध्यमिक धागे से मुख्य धागे पर कोड चलाना?

मैं जानना चाहता हूं कि माध्यमिक धागे के संदर्भ से मुख्य धागे पर कोड कैसे चलाया जाए। उदाहरण के लिए:

new Thread(new Runnable() { 
     public void run() { 
      //work out pi to 1,000 DP (takes a while!) 

      //print the result on the main thread 
     } 
    }).start(); 

उस तरह - मुझे पता है मेरे उदाहरण एक छोटे से गरीब जावा में जब से तुम कुछ बाहर मुद्रित करने के लिए मुख्य थ्रेड में होने की आवश्यकता नहीं है, और कहा कि स्विंग भी एक घटना कतार है - लेकिन जेनेरिक स्थिति जहां आपको चलाने की आवश्यकता हो सकती है, पृष्ठभूमि थ्रेड के संदर्भ में मुख्य धागे पर एक रननेबल कहें।

संपादित करें: -: पहले से

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0UL), ^{ 
    //do background thread stuff 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     //update UI 
    }); 
}); 

धन्यवाद तुलना के लिए यहाँ कैसे मैं ऑब्जेक्टिव-सी में ऐसा होता है!

उत्तर

25

किसी अन्य चलने वाले धागे को कुछ कोड भेजने के लिए कोई सार्वभौमिक तरीका नहीं है और कहें "अरे, आप, ऐसा करें।" आपको मुख्य धागे को ऐसे राज्य में रखना होगा जहां उसके पास काम प्राप्त करने के लिए एक तंत्र है और काम करने की प्रतीक्षा कर रहा है।

अन्य धागे से काम प्राप्त करने के लिए प्रतीक्षा करने के लिए मुख्य धागा स्थापित करने और इसे आने के रूप में चलाने का एक सरल उदाहरण यहां दिया गया है। जाहिर है आप वास्तव में कार्यक्रम को समाप्त करने के लिए एक रास्ता जोड़ना चाहते हैं और आगे ...!

public static final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(); 

public static void main(String[] args) throws Exception { 
    new Thread(new Runnable(){ 
     @Override 
     public void run() { 
      final int result; 
      result = 2+3; 
      queue.add(new Runnable(){ 
       @Override 
       public void run() { 
        System.out.println(result); 
       } 
      }); 
     } 
    }).start(); 

    while(true) { 
     queue.take().run(); 
    } 
} 
+0

आह ठीक है, इसलिए प्रैक्टिस में मुझे लगता है कि इस तरह की हार पृष्ठभूमि पृष्ठभूमि धागे का उपयोग करने के उद्देश्य से होती है क्योंकि मुख्य धागा पृष्ठभूमि धागे के लिए इंतजार कर रहा है। उस ने कहा, यह एक सुंदर साफ तंत्र की तरह दिखता है! मैं अब कतारों के बारे में और अधिक पढ़ूंगा! – Javawag

+0

आप निश्चित रूप से मुख्य धागा कुछ अन्य काम कर सकते हैं और केवल कुछ भी करने के बजाय अंतराल पर कतार को जांचें लेकिन उस पर अवरुद्ध करें। लेकिन किसी बिंदु पर यह घर-ब्रीइंग चीजों के लायक होने से रोकता है स्विंग के लिए पूरी तरह से अच्छे उपकरण प्रदान करता है :) – Affe

+0

असल में, मैं जो कर रहा हूं उसके लिए यह एक अच्छा विचार है - मैं स्विंग का उपयोग नहीं कर रहा हूं क्योंकि यह परियोजना वास्तव में एक साधारण गेम है Slick2d इंजन का उपयोग करके (अन्यथा आप सही हैं; मैं इसके लिए स्विंग के अंतर्निर्मित टूल का उपयोग करूंगा!) – Javawag

17

यदि आप एंड्रॉइड पर हैं, तो हैंडलर का उपयोग करके नौकरी करना चाहिए?

new Handler(Looper.getMainLooper()).post(new Runnable() { 
    @Override 
    public void run() { 
     ... 
    } 
}); 
+0

मुझे पता है कि 'runOnUIThread()' नामक एक विधि है लेकिन प्रत्येक परिस्थिति में कोड 'गतिविधि' में लिखा नहीं गया है। इस जवाब ने मुझे बहुत समय बचाया। धन्यवाद! – ManuQiao

+0

क्यू एंड्रॉइड के बारे में नहीं है, इसमें एंड्रॉइड टैग भी नहीं है। –

6

एक पुरानी चर्चा, लेकिन अगर यह मुख्य थ्रेड पर (एक नहीं विपरीत दिशा) आप भी वायदा के साथ यह कर सकते हैं अनुरोध भेजने की बात है।

public static void main(String[] args) throws InterruptedException, ExecutionException { 
    // create the task to execute 
    System.out.println("Main: Run thread"); 
    FutureTask<Integer> task = new FutureTask<Integer>(
      new Callable<Integer>() { 

       @Override 
       public Integer call() throws Exception { 
        // indicate the beginning of the thread 
        System.out.println("Thread: Start"); 

        // decide a timeout between 1 and 5s 
        int timeout = 1000 + new Random().nextInt(4000); 

        // wait the timeout 
        Thread.sleep(timeout); 

        // indicate the end of the thread 
        System.out.println("Thread: Stop after " + timeout + "ms"); 

        // return the result of the background execution 
        return timeout; 
       } 
      }); 
    new Thread(task).start(); 
    // here the thread is running in background 

    // during this time we do something else 
    System.out.println("Main: Start to work on other things..."); 
    Thread.sleep(2000); 
    System.out.println("Main: I have done plenty of stuff, but now I need the result of my function!"); 

    // wait for the thread to finish if necessary and retrieve the result. 
    Integer result = task.get(); 

    // now we can go ahead and use the result 
    System.out.println("Main: Thread has returned " + result); 
    // you can also check task.isDone() before to call task.get() to know 
    // if it is finished and do somethings else if it is not the case. 
} 

आपका इरादा पृष्ठभूमि में कई चीजें करते और परिणाम प्राप्त करने के लिए है, तो आप कुछ कतारों सेट कर सकते हैं के रूप में कहा: मूल उद्देश्य पृष्ठभूमि में कुछ निष्पादित करने के लिए और, जब यह समाप्त हो गया है, परिणाम प्राप्त करने के लिए है उपर्युक्त या आप कई वायदा में प्रक्रिया को विभाजित कर सकते हैं (सभी को एक बार शुरू करना या आवश्यकता होने पर एक नया शुरू करना), किसी अन्य भविष्य से भी)। यदि आप प्रत्येक कार्य को मानचित्र या सूची में संग्रहीत करते हैं, जो मुख्य थ्रेड में प्रारंभ होता है, तो आप किसी भी समय वायदा की जांच कर सकते हैं और जब वे पूरा कर लेते हैं तो उनके परिणाम प्राप्त कर सकते हैं।

2

आप 'यहां तक ​​कि प्रेषण धागे' का उपयोग करना चाह सकते हैं जहां अधिकांश घटनाएं चलती हैं। आप तो स्विंग उपयोग कर रहे हैं:

SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      Your code here. 
     } 
    }); 

या एक वर्ग है कि Runnable लागू करता है बना सकते हैं और यह invokeLater में पारित()।

संबंधित मुद्दे