Nee*_*eta 86 java multithreading android
我有一个方法HandlerThread
.一个值在内部发生变化Thread
,我想将它返回给test()
方法.有没有办法做到这一点?
public void test()
{
Thread uiThread = new HandlerThread("UIHandler"){
public synchronized void run(){
int value;
value = 2; //To be returned to test()
}
};
uiThread.start();
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*erg 72
通常你会这样做
public class Foo implements Runnable {
private volatile int value;
@Override
public void run() {
value = 2;
}
public int getValue() {
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以创建线程并检索值(假设已经设置了值)
Foo foo = new Foo();
Thread thread = new Thread(foo);
thread.start();
thread.join();
int value = foo.getValue();
Run Code Online (Sandbox Code Playgroud)
tl;dr
线程无法返回值(至少没有回调机制).您应该像普通类一样引用一个线程并询问该值.
Ada*_*man 69
您可以使用本地最终变量数组.变量必须是非基本类型,因此您可以使用数组.您还需要同步两个线程,例如使用CountDownLatch:
public void test()
{
final CountDownLatch latch = new CountDownLatch(1);
final int[] value = new int[1];
Thread uiThread = new HandlerThread("UIHandler"){
@Override
public void run(){
value[0] = 2;
latch.countDown(); // Release await() in the test thread.
}
};
uiThread.start();
latch.await(); // Wait for countDown() in the UI thread. Or could uiThread.join();
// value[0] holds 2 at this point.
}
Run Code Online (Sandbox Code Playgroud)
public void test() throws InterruptedException, ExecutionException
{
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() {
return 2;
}
};
Future<Integer> future = executor.submit(callable);
// future.get() returns 2 or raises an exception if the thread dies, so safer
executor.shutdown();
}
Run Code Online (Sandbox Code Playgroud)
Det*_*roc 27
您正在寻找的可能是Callable<V>
接口代替Runnable
,并使用Future<V>
对象检索值,这也让您等到计算出值.你可以通过一个ExecutorService
你可以得到的来实现这一目标Executors.newSingleThreadExecutor()
.
public void test() {
int x;
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Integer> result = es.submit(new Callable<Integer>() {
public Integer call() throws Exception {
// the other thread
return 2;
}
});
try {
x = result.get();
} catch (Exception e) {
// failed
}
es.shutdown();
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案怎么样?
它不使用Thread类,但它是并发的,并且在某种程度上它完全符合您的要求
ExecutorService pool = Executors.newFixedThreadPool(2); // creates a pool of threads for the Future to draw from
Future<Integer> value = pool.submit(new Callable<Integer>() {
@Override
public Integer call() {return 2;}
});
Run Code Online (Sandbox Code Playgroud)
现在你所要做的就是value.get()
在你需要获取返回的值时说,线程会在你给出value
一个值的第二个时间启动,所以你不必再说threadName.start()
了.
这Future
是对该计划的承诺,您向计划保证,您将在不久的将来获得它所需的价值
如果你.get()
在它完成之前调用它,那么调用它的线程将只是等到它完成
如果你想要调用方法的值,那么它应该等待线程完成,这使得使用线程有点毫无意义。
为了直接回答您的问题,该值可以存储在调用方法和线程都有引用的任何可变对象中。您可以使用 external this
,但除了用于琐碎的示例外,这不会特别有用。
关于问题中的代码的一点说明:扩展Thread
通常是糟糕的风格。事实上,不必要地扩展类是一个坏主意。我注意到您的run
方法由于某种原因是同步的。现在,在这种情况下,对象是Thread
您可能会干扰Thread
使用其锁定的任何对象(在参考实现中,与join
IIRC 有关)。
从 Java 8 开始,我们有CompletableFuture
. 在您的情况下,您可以使用该方法supplyAsync
在执行后获取结果。
请在这里找到一些参考。
CompletableFuture<Integer> completableFuture
= CompletableFuture.supplyAsync(() -> yourMethod());
completableFuture.get() //gives you the value
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
177683 次 |
最近记录: |