2014-09-19 78 views
0

我犯了這樣一個波紋管螺紋:如何從線程返回值(JAVA)

public class MyThread implements Runnable { 
    private int temp; 

    public MyThread(int temp){ 
    this.temp=temp; 
    } 

    @Override 
    public void run() { 
    temp+=10; 
    return; 
    } 

    public int getTemp() { 
    return temp; 
    } 
} 

但是當我嘗試通過getTemp使用溫度,我得到0

class Main { 
    MyThread foo = new MyThread(10); 
    Thread a = new Thread(foo); 
    a.start(); 
    int aa = foo.getTemp();  
    System.out.println(aa); 
} 

我只是想使用我在線程中做的計算將其存儲在一些變量中供以後使用。

回答

3

或者簡單地添加

... 
a.start(); 
a.join(); // Add this 
... 

等待線程得到結果之前完成。

你的問題是,你正在嘗試獲得結果之前,已計算。在獲得結果之前,您應該等待線程完成。這個答案可能不是最好的,但最簡單。由於其他人已經使用了Executors類,我不想重複他們的答案。不過,在轉移到執行程序之前,請先熟悉一下Thread和它的方法,以幫助您更好地理解線程,因爲從您的文章看來,您可能是這方面的新手。

感謝l4mpi (on the meta site)指出缺乏解釋。

+0

因此顯着降低了使用多線程的收益。這不是最佳解決方案。 – Dariusz 2014-09-19 08:28:50

+0

1-最簡單,最簡潔的答案。 2 Op不具有多個線程。 3-有人已經給出了與多線程一起使用的答案。 4-去其他地方的巨魔。 – TedTrippin 2014-09-19 08:53:20

+0

爲什麼downvote一個正確的答案? – TedTrippin 2014-09-19 08:53:50

0

在這種情況下,你必須使用可贖回的,而不是Runnable接口(非常相似): http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

public class MyThread implements Callable<Integer> { 

    private int temp; 

    public MyThread(int temp){ 
     this.temp=temp; 
    } 
    @Override 
    public Integer call() { 
     temp+=10; 
     return temp; 
    } 

} 


public static void main(String[] args) throws InterruptedException, ExecutionException { 
      ExecutorService service = Executors.newSingleThreadExecutor(); 
      MyThread myTask = new MyThread(10); 
      Future<Integer> future = service.submit(myTask); 
      Integer result = future.get(); 
      System.out.println(result); 
} 
+0

我們可以從這個方法返回數組嗎? – user3512121 2014-09-19 09:02:06

0

你可以試試這些代碼。通過使用未來可以保持價值迴歸時,螺紋:代替Runnable

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

/** 
* @author mike 
* @date Sep 19, 2014 
* @description 
*/ 
public class Calc { 
    private static class MyCallable implements Callable<Integer> { 
     private int temp = 0; 

     public MyCallable(int temp) { 
      this.temp = temp; 
     } 

     @Override 
     public Integer call() { 
      temp += 10; 
      return temp; 
     } 
    } 

    public static void main(String[] args) { 
     MyCallable foo = new MyCallable(10); 
     try { 
      Future<Integer> result = Executors.newCachedThreadPool().submit(foo); 
      System.out.println(result.get()); 
     } catch (InterruptedException | ExecutionException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
3

使用Callable,它會返回一個未來,你可以使用一旦完成檢索值。

如果您願意,您可以使用命名的類而不是lambda expression

import java.util.concurrent.*; 

public class ReturnValueFromThread { 
    public static void main(String[] args) throws Exception { 
     ExecutorService executor = Executors.newSingleThreadExecutor(); 
     Future<Object> foo = executor.submit(() -> { 
      return doWork(); 
     }); 

     System.out.println("We will reach this line before doWork is done."); 
     System.out.println(foo.get()); // Will wait until the value is complete 
     executor.shutdown(); 
    } 

    private static double doWork() throws Exception { 
     Thread.sleep(2000); 
     return Math.random(); 
    } 
} 
+0

我們可以從這個方法返回數組嗎? – user3512121 2014-09-19 09:02:42

+0

你試過了嗎?發生了什麼? – folkol 2014-09-19 09:13:53

0

有幾種方法可以通過線程「共享」變量。

您的代碼存在的問題是您傳遞的是int,這是passed by value。這意味着tempthis.temp不是同一個變量。

使用Future作爲其他答案的建議是一種可以共享變量的方法。使用Future,可以確保線程在實際獲取該線程執行結果之前完成,因此可能與您更相關。

的是線程安全的線程間共享變量的其他方式,但不保證該線程執行結束:

  • 傳遞一個AtomicInteger,並使用set方法來設置值。使用​​返回線程值的getter方法。