java异步的await_5种必会的Java异步调用转同步的方法你会几种

更新时间:2023-07-01 19:43:16 阅读: 评论:0

java异步的await_5种必会的Java异步调⽤转同步的⽅法你会
⼏种
Sunny先来说⼀下对异步和同步的理解:
同步调⽤:调⽤⽅在调⽤过程中,持续等待返回结果。
异步调⽤:调⽤⽅在调⽤过程中,不直接等待返回结果,⽽是执⾏其他任务,结果返回形式通常为回调函数。
党员学习书籍
其实,两者的区别还是很明显的,这⾥也不再细说,我们主要来说⼀下Java如何将异步调⽤转为同步。换句话说,就是需要在异步调⽤过程中,持续阻塞⾄获得调⽤结果。
不卖关⼦,先列出五种⽅法,然后⼀⼀举例说明:
使⽤wait和notify⽅法
使⽤条件锁
Future
世好啤酒
使⽤CountDownLatch
使⽤CyclicBarrier
0.构造⼀个异步调⽤
⾸先,写demo需要先写基础设施,这⾥的话主要是需要构造⼀个异步调⽤模型。异步调⽤类:
public class AsyncCall {
private Random random = new Random(System.currentTimeMillis());
private ExecutorService tp = wSingleThreadExecutor();
//demo1,2,4,5调⽤⽅法
public void call(BaDemo demo){
new Thread(()->{
long res = Int(10);
try {
星光奖Thread.sleep(res*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
demo.callback(res);
}).start();
}
//demo3调⽤⽅法
public Future futureCall(){
return tp.submit(()-> {
long res = Int(10);
try {
Thread.sleep(res*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return res;
});
}
public void shutdown(){
tp.shutdown();
halloween
}
}
我们主要关⼼call⽅法,这个⽅法接收了⼀个demo参数,并且开启了⼀个线程,在线程中执⾏具体的任务,并利⽤demo的callback⽅法进⾏回调函数的调⽤。⼤家注意到了这⾥的返回结果就是⼀个[0,10)的长整型,并且结果是⼏,就让线程sleep多久——这主要是为了更好地观察实验结果,模拟异步调⽤过程中的处理时间。
⾄于futureCall和shutdown⽅法,以及线程池tp都是为了demo3利⽤Future来实现做准备的。
demo的基类:
public abstract class BaDemo {
protected AsyncCall asyncCall = new AsyncCall();
public abstract void callback(long respon);
public void call(){
System.out.println("发起调⽤");
asyncCall.call(this);
System.out.println("调⽤返回");
}
}
BaDemo⾮常简单,⾥⾯包含⼀个异步调⽤类的实例,另外有⼀个call⽅法⽤于发起异步调⽤,当然还有⼀个抽象⽅法callback需要每个demo去实现的——主要在回调中进⾏相应的处理来达到异步调⽤转同步的⽬的。
1. 使⽤wait和notify⽅法
这个⽅法其实是利⽤了锁机制,直接贴代码:
public class Demo1 extends BaDemo{
private final Object lock = new Object();
@Override
public void callback(long respon) {
System.out.println("得到结果");
System.out.println(respon);
System.out.println("调⽤结束");
synchronized (lock) {
}
}
public static void main(String[] args) {
Demo1 demo1 = new Demo1();
demo1.call();
synchronized (demo1.lock){
try {
demo1.lock.wait();
植字组词} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("主线程内容");
}
}
可以看到在发起调⽤后,主线程利⽤wait进⾏阻塞,等待回调中调⽤notify或者notifyAll⽅法来进⾏唤醒。注意,和⼤家认知的⼀样,这⾥wait和notify都是需要先获得对象的锁的。在主线程中最后我们打印了⼀个内容,这也是⽤来验证实验结果的,如果没有wait和notify,主线程内容会紧随调⽤内容⽴刻打印;⽽像我们上⾯的代码,主线程内容会⼀直等待回调函数调⽤结束才会进⾏打印。
没有使⽤同步操作的情况下,打印结果:
发起调⽤
调⽤返回
主线程内容
得到结果
1
调⽤结束
⽽使⽤了同步操作后:
发起调⽤
调⽤返回
得到结果
9
调⽤结束
主线程内容
2. 使⽤条件锁
和⽅法⼀的原理类似:
public class Demo2 extends BaDemo {
private final Lock lock = new ReentrantLock();
private final Condition con = wCondition();
@Override
public void callback(long respon) {
System.out.println("得到结果");
System.out.println(respon);
System.out.println("调⽤结束");
lock.lock();
try {
con.signal();
}finally {
捆绑贵妇人在线lock.unlock();
}
}
public static void main(String[] args) {
Demo2 demo2 = new Demo2();
demo2.call();
demo2.lock.lock();
try {
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
demo2.lock.unlock();
腾讯网名
}
System.out.println("主线程内容");
}
}
基本上和⽅法⼀没什么区别,只是这⾥使⽤了条件锁,两者的锁机制有所不同。
3. Future
使⽤Future的⽅法和之前不太⼀样,我们调⽤的异步⽅法也不⼀样。
public class Demo3{
private AsyncCall asyncCall = new AsyncCall();
public Future call(){
Future future = asyncCall.futureCall();
asyncCall.shutdown();
return future;
}
public static void main(String[] args) {
Demo3 demo3 = new Demo3();
System.out.println("发起调⽤");
Future future = demo3.call();
System.out.println("返回结果");
while (!future.isDone() && !future.isCancelled());
try {
System.out.());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("主线程内容");
}
}
我们调⽤futureCall⽅法,⽅法中会想线程池tp提交⼀个Callable,然后返回⼀个Future,这个Future就是我们demo3中call中得到的,得到future对象之后就可以关闭线程池啦,调⽤asyncCall的shutdown⽅法。关于关闭线程池这⾥有⼀点需要注意,我们回过头来看看asyncCall的shutdown⽅法:
public void shutdown(){
tp.shutdown();
}
发现只是简单调⽤了线程池的shutdown⽅法,然后我们说注意的点,这⾥最好不要⽤tp的shutdownNow⽅法,该⽅法会试图去中断线程中中正在执⾏的任务;也就是说,如果使⽤该⽅法,有可能我们的future所对应的任务将被中断,⽆法得到执⾏结果。
然后我们关注主线程中的内容,主线程的阻塞由我们⾃⼰来实现,通过future的isDone和isCancelled来判断执⾏状态,⼀直到执⾏完成或被取消。随后,我们打印get到的结果。
我要做一棵树
4. 使⽤CountDownLatch

本文发布于:2023-07-01 19:43:16,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1072732.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:结果   需要   主线   内容   线程   回调
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图