java怎么写异步⽅法_Java异步实现的⼏种⽅式
1. jdk1.8之前的Future
jdk并发包⾥的Future代表了未来的某个结果,当我们向线程池中提交任务的时候会返回该对象,可以通过future获得执⾏的结果,但是jdk1.8之前的Future有点鸡肋,并不能实现真正的异步,需要阻塞的获取结果,或者不断的轮询。
通常我们希望当线程执⾏完⼀些耗时的任务后,能够⾃动的通知我们结果,很遗憾这在原⽣jdk1.8之前是不⽀持的,但是我们可以通过第三⽅的库实现真正的异步回调。
/**
* jdk1.8之前的Future
* @author Administrator
*/
public class JavaFuture {
public static void main(String[] args) throws Throwable, ExecutionException {
ExecutorService executor = wFixedThreadPool(1);
Future f = executor.submit(new Callable() {
@Override
public String call() throws Exception {
System.out.println("task started!");
longTimeMethod();
System.out.println("task finished!");
return "hello";
}
});
/
/此处get()⽅法阻塞main线程
System.out.());
System.out.println("main thread is blocked");
}
}
如果想获得耗时操作的结果,可以通过get()⽅法获取,但是该⽅法会阻塞当前线程,我们可以在做完剩下的某些⼯作的时候调⽤get()⽅法试图去获取结果。
也可以调⽤⾮阻塞的⽅法isDone来确定操作是否完成,isDone这种⽅式有点⼉类似下⾯的过程:
2. jdk1.8开始的Future
直到jdk1.8才算真正⽀持了异步操作,jdk1.8中提供了lambda表达式,使得java向函数式语⾔⼜靠近了⼀步。借助jdk原⽣的CompletableFuture可以实现异步的操作,同时结合lambada表达式⼤⼤简化了代码量。代码例⼦如下:
package netty_promise;
import urrent.CompletableFuture;
import urrent.ExecutionException;
import urrent.ExecutorService;
import urrent.Executors;
import java.util.function.Supplier;
/**
* 基于jdk1.8实现任务异步处理
* @author Administrator
*/
public class JavaPromise {
jdk怎么使用public static void main(String[] args) throws Throwable, ExecutionException { // 两个线程的线程池
ExecutorService executor = wFixedThreadPool(2);
//jdk1.8之前的实现⽅式
CompletableFuture future = CompletableFuture.supplyAsync(new Supplier() { @Override
public String get() {
System.out.println("task started!");
try {
//模拟耗时操作
longTimeMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
return "task finished!";
}
}, executor);
//采⽤lambada的实现⽅式
future.thenAccept(e -> System.out.println(e + " ok"));
System.out.println("main thread is running");
}
}
实现⽅式类似下图:
3. Spring的异步⽅法
先把longTimeMethod 封装到Spring的异步⽅法中,这个异步⽅法的返回值是Future的实例。这个⽅法⼀定要写在Spring管理的类中,注意注解@Async。
@Service
public class AsynchronousService{
@Async
public Future springAsynchronousMethod(){
Integer result = longTimeMethod();
return new AsyncResult(result);
}
}
其他类调⽤这个⽅法。这⾥注意,⼀定要其他的类,如果在同类中调⽤,是不⽣效的。
@Autowired
private AsynchronousService asynchronousService;
public void useAsynchronousMethod(){
Future future = asynchronousService.springAsynchronousMethod();
<(1000, TimeUnit.MILLISECONDS);
}
其实Spring只不过在原⽣的Future中进⾏了⼀次封装,我们最终获得的还是Future实例。
4. Java如何将异步调⽤转为同步
换句话说,就是需要在异步调⽤过程中,持续阻塞⾄获得调⽤结果。
使⽤wait和notify⽅法
使⽤条件锁
Future
使⽤CountDownLatch
使⽤CyclicBarrier
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论