2014-09-19 79 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方法。