2010-06-29 16 views
41

Diyelim ki bu basit örneğimiz var:Bir iş, işini bitirdikten sonra nasıl bir değer döndürür?

public Example extends Thread{ 

    String temp;  

    public Example(){ 
    } 

    @Override 
    public void run(){ 
     . 
     . 
     . 
     . 
     temp = "a_value"; 
    } 

    public static void main(String[] args) { 

     Example th = new Example(); 
     th.start(); 
    } 

} 

İşi bitirdikten sonra iş parçacığı String temp'ını nasıl iade edebilir?

+1

'th.start()' olmalıdır. Ve iş parçacığından bir değer döndürme yöntemlerinden birini uyguladınız. –

cevap

7

Bunu, Observer deseniyle elde edebilirsiniz. iş parçacığını bitirdiğinde tüm dinleyicilere bittiğini bildirir ve değeri (bir alıcıdan) alabilirler. Veya önceden hesaplanmış değeri bile gönderebilir. Ya da bir görevi kullanabilirsiniz, bkz. FutureTask, bir sonuç döndüren bir runnable (gerçekten de aşağıda bir Callable) ve istisnalar atabilirsiniz.

11

Arabirim javadoc Future'a bakın. Bunu nasıl yapacağınızı gösteren örnek kullanımı vardır. (1.5 ve daha yeni sürümlerde mevcuttur) yerine Runnable (nispeten) yeni Callable<T> ait

63

yararlanın:

import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 


public class Main { 

    public static void main(final String[] argv) { 
     final ExecutorService service; 
     final Future<String> task; 

     service = Executors.newFixedThreadPool(1);   
     task = service.submit(new Foo()); 

     try { 
      final String str; 

      // waits the 10 seconds for the Callable.call to finish. 
      str = task.get(); // this raises ExecutionException if thread dies 
      System.out.println(str); 
     } catch(final InterruptedException ex) { 
      ex.printStackTrace(); 
     } catch(final ExecutionException ex) { 
      ex.printStackTrace(); 
     } 

     service.shutdownNow(); 
    } 
} 

class Foo implements Callable<String> { 
    public String call() { 
     try { 
      // sleep for 10 seconds 
      Thread.sleep(10 * 1000); 
     } catch(final InterruptedException ex) { 
      ex.printStackTrace(); 
     } 

     return ("Hello, World!"); 
    } 
} 
+2

"(nispeten) yeni" Neye göre? Hizmet ömrünün sona ermesini tamamlamış bir versiyonda tanıtıldı. –

+20

Sürümler ile ilgili ... 1.6 geçerli, 1.5 olarak piyasaya sürüldü. Onu, 1.0'da bulunan Thread ile karşılaştır. Öğrencilerin öğrendiği kitapların çoğunun içinde Callable bulunmuyor. – TofuBeer

+7

her zaman örneklerde olduğu gibi wtf merak ediyorum merak ediyorum. – jiduvah

0

sen istemiyorsanız: Burada

bir (basit) bir örnektir Callable nesnelerini kullanmak için çözümü takas etmek için kuyrukları da kullanabilir ve sonucu iş parçacığından bu şekilde döndürebilirsiniz. Böyle
ben yeniden yazdım senin örnek: senkronizasyonu ve eşzamanlılık düşünmek zorundadır

import java.util.PriorityQueue; 
import java.util.Queue; 

public class GetResultFromThread { 
    public static void main(String[] args) throws Exception { 
     Queue<String> queue = new PriorityQueue<String>(); 
     int expectedResults = 2; 
     for (int i = 0; i < expectedResults; i++) { 
      new Example(queue).start(); 
     } 

     int receivedResults = 0; 
     while (receivedResults < expectedResults) { 
      if (!queue.isEmpty()) { 
       System.out.println(queue.poll()); 
       receivedResults++; 
      } 
      Thread.sleep(1000); 
     } 
    } 
} 

class Example extends Thread { 
    private final Queue<String> results; 

    public Example(Queue<String> results) { 
     this.results = results; 
    } 

    @Override 
    public void run() { 
     results.add("result from thread"); 
    } 
} 

Not!

+3

Sadece aşağı ok tıklayarak ve bunun kötü bir çözüm olduğunu söylemek yerine nedenini açıklarsanız iyi olur. Teşekkürler – thomasb

+0

Aslında bu @ Martin'in çözümü çok akıllı, bunun için teşekkürler – Benvorth

İlgili konular