Java 将来会有结果吗?
我希望从一个方法中得到一个结果,这个方法可能需要一段时间才能完成,并且实际上不会返回对象,所以我希望尽可能有效地处理它。下面是我试图实现的一个例子:Java 将来会有结果吗?,java,asynchronous,runnable,callable,futuretask,Java,Asynchronous,Runnable,Callable,Futuretask,我希望从一个方法中得到一个结果,这个方法可能需要一段时间才能完成,并且实际上不会返回对象,所以我希望尽可能有效地处理它。下面是我试图实现的一个例子: public static void main (String[] args) { Object obj = someMethod(); System.out.println("The object is" + obj + ", wooh!"); } public void callObj
public static void main (String[] args) {
Object obj = someMethod();
System.out.println("The object is" + obj + ", wooh!");
}
public void callObject() {
// Sends request for the object
}
public void receiveObject(Object object) {
// Received the object
}
public Object someMethod() {
callObject();
// delay whilst the object is being received
// return received object once received, but how?
}
方法callObject将调用以获取对象,但是在对象处于中时会调用另一个方法。我希望someMethod()能够调用对象,然后返回它最终接收到的内容,即使实际的调用和接收是不同的方法
我已经考虑过使用FutureTasks和Callables,我认为这是未来的发展方向,我只是不太确定如何实现它
对不起,如果我解释得不太清楚,我会在必要时提供更多信息
谢谢 您可以编写一个方法,异步启动一些长时间运行的任务。然后,您将返回一个future对象,该对象为空,但在长时间运行的任务完成后将被填充。在其他编程语言中,这称为承诺 下面是一个简单的例子。我创建了一个名为
someLongAsyncOperation
的方法,它执行一些需要一段时间的操作。为了模拟这种情况,我只需在生成答案之前睡眠3秒钟
import java.util.UUID;
import java.util.concurrent.*;
public class Test {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
public Future<MyAnswer> someLongAsyncOperation(){
Future<MyAnswer> future = executorService.submit(() -> {
Thread.sleep(3000);
return new MyAnswer(UUID.randomUUID().toString());
});
return future;
}
public static void main(String[] args) throws Exception {
System.out.println("calling someLongAsyncOperation ...");
Future<MyAnswer> future = new Test().someLongAsyncOperation();
System.out.println("calling someLongAsyncOperation done.");
// do something else
System.out.println("wait for answer ...");
MyAnswer myAnswer = future.get();
System.out.printf("wait for answer done. Answer is: %s", myAnswer.value);
executorService.shutdown();
}
static class MyAnswer {
final String value;
MyAnswer(String value) {
this.value = value;
}
}
}
这将通过调用异步操作并等待结果,使其再次同步
EDIT2
下面是另一个使用等待/通知的示例:
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test2 {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
private Object receivedObject;
private final Object mutex = new Object();
public static void main (String[] args) throws InterruptedException {
Object obj = new Test2().someMethod();
System.out.println("The object is" + obj + ", wooh!");
executorService.shutdown();
}
public void callObject() {
System.out.println("callObject ...");
// Sends request for the object asynchronously!
executorService.submit(() -> {
// some wait time to simulate slow request
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// provide object to callback
receiveObject(UUID.randomUUID().toString());
});
System.out.println("callObject done.");
}
public void receiveObject(Object object) {
System.out.println("receiveObject ...");
synchronized (mutex) {
this.receivedObject = object;
mutex.notify();
}
System.out.println("receiveObject done.");
}
public Object someMethod() throws InterruptedException {
System.out.println("someMethod ...");
synchronized (mutex) {
callObject();
while(this.receivedObject == null){
mutex.wait();
}
}
System.out.println("someMethod done.");
return this.receivedObject;
}
}
someMethod
等待receivedObject
存在<代码>接收对象到达时通知。您需要回调:
private abstract class Callback<T>{
run(T object);
}
public Object someMethod() {
callObject(new Callback<Object>()
{
@Override
public void run(Object object)
{
System.out.println("The object is" + object + ", wooh!");
}
})
}
public void callObject(Callback<Object> callback) {
// Sends request for the object
callback.run(object);
}
私有抽象类回调{
运行(T对象);
}
公共对象方法(){
callObject(新的回调()
{
@凌驾
公共无效运行(对象)
{
System.out.println(“对象是“+object+”,wooh!”);
}
})
}
公共void callObject(回调){
//发送对象的请求
callback.run(对象);
}
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
类ThreadExample实现可调用{
@凌驾
公共字符串调用()引发异常{
//TODO自动生成的方法存根
返回“Ashish”;
}
}
公共类示例{
公共静态void main(字符串a[])引发InterruptedException、ExecutionException{
ExecutorService ExecutorService=Executors.newFixedThreadPool(1);
List objList=new ArrayList();
对于(int i=0;iLooks,但是对象的接收从何而来?您在回调中得到它,您可以从那里而不是System.out调用它。当然,您需要确保回调在后线程上执行,回调在主线程上执行。但这取决于您使用的线程系统nt来使用。好的,但是通过引用结果,它怎么知道结果已经收到了?你只在收到结果时调用回调。然后回调将它作为一个参数。我知道了,哪个方法调用回调?这是一个很好的起点,但我不确定接收方法将如何提供SomeLongAsync操作结果如何?听起来你希望在操作完成后调用receiveObject
。这更像是一个回调,而不是未来。让我试着提供一个例子…是的,这就是我要说的-抱歉!但有一点必须清楚,如果你使用异步方式,使用未来或回调机制才有意义没有。如果someMethod
只是等待异步工作完成,那么首先异步做有什么意义呢?没有太多的关注它是否必须是异步的(我不太确定哪一个是最好的),但其思想是,我可以在调用结果后立即引用它,而无需执行其余代码。Object result=getResult();//执行和获取结果System.out.println(result)需要时间;虽然此代码片段可能会解决此问题,但它不会解释为什么或如何回答此问题。请注意,这确实有助于提高您文章的质量。请记住,您将为将来的读者回答此问题,而这些人可能不知道您的代码建议的原因。您可以使用按钮来改进这是获得更多选票和声誉的答案!
private abstract class Callback<T>{
run(T object);
}
public Object someMethod() {
callObject(new Callback<Object>()
{
@Override
public void run(Object object)
{
System.out.println("The object is" + object + ", wooh!");
}
})
}
public void callObject(Callback<Object> callback) {
// Sends request for the object
callback.run(object);
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class ThreadExample implements Callable<String>{
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "Ashish";
}
}
public class FutureThreadExample {
public static void main(String a[]) throws InterruptedException, ExecutionException {
ExecutorService executorService=Executors.newFixedThreadPool(1);
List <Future<String>>objList=new ArrayList<Future<String>>();
for(int i=0;i<10;i++) {
Future<String> obj=executorService.submit(new ThreadExample());
objList.add(obj);
}
for( Future<String> fut:objList) {
System.out.println(fut.get());
}
executorService.shutdown();
}
}