我做了一个像这样的线程:
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);
}
我只想使用我在线程中执行的计算存储在某些变量中供以后使用。
答案 0 :(得分:3)
使用Callable代替Runnable,它会返回一个可用于在完成后检索值的Future。
如果您愿意,可以使用命名类而不是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();
}
}
答案 1 :(得分:3)
或者只需添加
...
a.start();
a.join(); // Add this
...
在获得结果之前等待线程完成。
您的问题是您在计算结果之前尝试获取结果。在获得结果之前,您应该等待线程完成。这个答案可能不是最好的,但却是最简单的。由于其他人已经使用过Executors类,我不想重复他们的答案。但是,在转到Executors之前,我会熟悉Thread及其方法,以帮助您更好地理解线程,因为从您的帖子中看来,您可能是这方面的新手。
感谢l4mpi (on the meta site)指出缺乏解释。
答案 2 :(得分:0)
在这种情况下,您必须使用Callable而不是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);
}
答案 3 :(得分:0)
您可以尝试这些代码。通过使用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();
}
}
}
答案 4 :(得分:0)
有几种方法可以与Threads“共享”变量。
您的代码存在的问题是您传递的int
是passed by value。这意味着temp
和this.temp
不是同一个变量。
使用Future
作为其他答案建议是一种可以共享变量的方法。使用Future
,您可以确保在实际获取该Threads执行结果之前Thread已完成,因此可能与您更相关。
在线程安全的线程之间共享变量的其他方法,但不保证线程已完成执行:
set
方法设置值。 synchronized
getter方法。