如何从线程返回值(java)

如何从线程返回值(java),java,multithreading,Java,Multithreading,我做了一条像下面这样的线: 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; } } 但是

我做了一条像下面这样的线:

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使用temp时,我得到了0

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

我只想使用我在线程中进行的计算,将其存储在一些变量中以供以后使用。

在这种情况下,您必须使用Callable而不是Runnable(非常类似):

公共类MyThread实现可调用{
私人内部温度;
公共数据读取(int temp){
这个.temp=temp;
}
@凌驾
公共整数调用(){
温度+=10;
返回温度;
}
}
公共静态void main(字符串[]args)引发InterruptedException、ExecutionException{
ExecutorService=Executors.newSingleThreadExecutor();
MyThread myTask=新的MyThread(10);
Future=service.submit(我的任务);
整数结果=future.get();
系统输出打印项次(结果);
}

您可以尝试这些代码。通过使用Future,您可以在线程结束时保留返回值:

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();
        }
    }
}
import java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
/**
*@作者迈克
*@日期2014年9月19日
*@说明
*/
公共类计算{
私有静态类MyCallable实现了Callable{
私人内部温度=0;
公共MyCallable(int-temp){
this.temp=temp;
}
@凌驾
公共整数调用(){
温度+=10;
返回温度;
}
}
公共静态void main(字符串[]args){
MyCallable foo=新的MyCallable(10);
试一试{
未来结果=Executors.newCachedThreadPool().submit(foo);
System.out.println(result.get());
}捕获(中断异常|执行异常e){
e、 printStackTrace();
}
}
}
使用而不是,它将返回一个将来,您可以使用它在完成后检索值

如果愿意,可以使用命名类而不是

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();
    }
}
import java.util.concurrent.*;
公共类ReturnValueFromThread{
公共静态void main(字符串[]args)引发异常{
ExecutorService executor=Executors.newSingleThreadExecutor();
Future foo=执行者提交(()->{
返回定位销();
});
System.out.println(“我们将在工作完成之前到达这一行”);
System.out.println(foo.get());//将等待值完成
executor.shutdown();
}
private static double doWork()引发异常{
《睡眠》(2000年);
返回Math.random();
}
}
有几种方法可以与线程“共享”变量

代码的问题是您正在传递一个
int
,它是。这意味着
temp
This.temp
不是同一个变量

如其他答案所示,使用
未来
是共享变量的一种方式。使用
Future
,您可以确保线程在实际获取该线程执行的结果之前已经完成,因此可能与您更相关

在线程之间共享变量的其他方法是线程安全的,但不能保证线程已完成执行:

  • 传递并使用
    set
    方法设置值
  • 使用返回Threads值的
    synchronized
    getter方法
或只需添加

...
a.start();
a.join(); // Add this
...
在得到结果之前等待线程完成

您的问题是,您试图在计算结果之前得到结果。在得到结果之前,应该等待线程完成。这个答案也许不是最好的,但却是最简单的。由于其他人已经使用了Executors类,我不想重复他们的答案。然而,在进入Executors之前,我会先熟悉Thread及其方法,以帮助您更好地理解threads,因为从您的帖子来看,您可能是这方面的新手


感谢您指出缺乏解释。

因此大大降低了使用多线程的收益。这不是一个最优的解决方案。1-这是最简单、最简洁的答案。2-Op没有多个线程。3-有人已经给出了多线程使用的答案。因为我认为它不应该用于同步并行计算操作。我认为
Thread.join()
应该只在应用程序关闭并且线程还有一些工作要完成时使用-至少我现在想不出还有什么好的用途,也许有一个。但不是这个。除此之外:看看downvote按钮上的提示,上面写着:“这个答案没有用”。我不仅认为它没有用,而且认为它会助长坏的做法。这篇文章将在上讨论。有时,您必须使用异步进程(或被迫在其他线程上处理,请参阅STA线程),但也必须阻止当前线程,直到该进程完成。所以有些情况下你必须这样做。我们可以从这个方法返回数组吗?我们可以从这个方法返回数组吗?你试过了吗?发生了什么事?在您的代码片段中,doWork()似乎是一个常规方法,在本例中可调用。在
()->{
部分。Google“Java函数接口”。
...
a.start();
a.join(); // Add this
...