我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java中异步转同步的方法有哪些

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java中异步转同步的方法有哪些

今天小编给大家分享一下Java中异步转同步的方法有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

一、问题

应用场景

应用中通过框架发送异步命令时,不能立刻返回命令的执行结果,而是异步返回命令的执行结果。

那么,问题来了,针对应用中这种异步调用,能不能像同步调用一样立刻获取到命令的执行结果,如何实现异步转同步?

二、分析

首先,解释下同步和异步

  • 同步,就是发出一个调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作。

  • 异步,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作。当这个调用完成后,一般通过状态、通知和回调来通知调用者。

对于异步调用,调用的返回并不受调用者控制。

异步转同步主要实现思路:所有实现原理类似,是在发出调用的线程中进行阻塞等待结果,调用完成后通过回调、设置共享状态或通知进行阻塞状态的解除,继续执行后续操作。

三、实现方法

通常,实现中,不会无限的等待,一般会设定一个超时时间,具体超时时间根据具体场景确定。

下面以回调的方式介绍几种常用实现异步转同步的方法:

1.轮询与休眠重试机制

采用轮询与休眠重试机制,线程将反复在休眠和测试状态条件中之间切换,直到超时或者状态条件满足继续向下执行。这种方式,超时时间控制不准确,sleep时间需要在响应性和CPU使用率之间进行权衡。

private static long MILLIS_OF_WAIT_TIME = 300000L;// 等待时间 5分钟private final Object lock = new Object();//3.结果返回后进行回调,解除阻塞@Overridepublic void callback(AsynResponse response){    synchronized(lock){        //设置状态条件} public Result getResult() throws ErrorCodeException {// 1.异步调用 // 2.阻塞等待异步响应    long future = System.currentTimeMillis() + MILLIS_OF_WAIT_TIME;    long remaining = MILLIS_OF_WAIT_TIME;//剩余等待时间    while(remaining > 0){        synchronized(lock){            if(状态条件未满足){                remaining = future - System.currentTimeMillis();                Thread.sleep(时间具体场景确定);            }        }  ````} //4.超时或结果正确返回,对结果进行处理         return result;}

2.wait/notify

任意一个Java对象,都拥有一组监视器方法(wait、notify、notifyAll等方法),这些方法和synchronized同步关键字配合,可以实现等待/通知模式。但是使用wait/notify,使线程的阻塞/唤醒对线程本身来说是被动的,要准确的控制哪个线程是很困难的,所以是要么随机唤醒等待在条件队列上一个线程(notify),要么唤醒所有的(notifyAll,但是很低效)。当多个线程基于不同条件在同一条件队列上等待时,如果使用notify而不是notifyAll,很容易导致信号丢失的问题,所以必须谨慎使用wait/notify方法。

private static long MILLIS_OF_WAIT_TIME = 300000L;// 等待时间 5分钟private final Object lock = new Object();//3.结果返回后进行回调,解除阻塞@Overridepublic void callback(AsynResponse response){    synchronized(lock){        lock.notifyAll();} public Result getResult() throws ErrorCodeException {// 1.异步调用 // 2.阻塞等待异步响应    long future = System.currentTimeMillis() + MILLIS_OF_WAIT_TIME;    long remaining = MILLIS_OF_WAIT_TIME;//剩余等待时间    synchronized(lock){        while(条件未满足  && remaining > 0){ //被通知后要检查条件            lock.wait(remaining);            remaining = future - System.currentTimeMillis();        }  ````}    //4.超时或结果正确返回,对结果进行处理    return result;}

3.Lock Condition

使用Lock的Condition队列的实现方式和wait/notify方式类似,但是Lock支持多个Condition队列,并且支持等待状态中响应中断。

private static long SECONDS_OF_WAIT_TIME = 300L;// 等待时间 5分钟private final Lock lock = new ReentrantLock();private final Condition condition = lock.newCondition();//3.结果返回后进行回调,解除阻塞@Overridepublic void callback(AsynResponse response){    lock.lock();//这是前提    try {        condition.signal();    }finally {        lock.unlock();    }}public Result getResult() throws ErrorCodeException {// 1.异步调用// 2.阻塞等待异步响应    lock.lock();//这是前提    try {        condition.await();    } catch (InterruptedException e) {        //TODO    }finally {        lock.unlock();    }//4.超时或结果正确返回,对结果进行处理    return result;}

4.CountDownLatch

使用CountDownLatch可以实现异步转同步,它好比计数器,在创建实例CountDownLatch对象的时候传入数字,每使用一次 countDown() 方法计数减1,当数字减到0时, await()方法后的代码将可以执行,未到0之前将一直阻塞等待。

private static long SECONDS_OF_WAIT_TIME = 300L;// 等待时间 5分钟private final CountDownLatch countDownLatch = new CountDownLatch(1);//3.结果返回后进行回调,解除阻塞@Overridepublic void callback(AsynResponse response){    countDownLatch.countDown();}public Result getResult() throws ErrorCodeException {    // 1.异步调用    // 2.阻塞等待异步响应    try {        countDownLatch.await(SECONDS_OF_WAIT_TIME, TimeUnit.SECONDS);    } catch (InterruptedException e) {        //TODO    }//4.超时或结果正确返回,对结果进行处理    return result;}

5.CyclicBarrier

让一组线程达到一个屏障(也可以叫同步点)时被阻塞,直到等待最后一个线程到达屏障时,屏障才开门,所有被屏障拦截的线程才会继续执行。

每个线程通过调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前的的线程被阻塞。

private static long SECONDS_OF_WAIT_TIME = 300L;// 等待时间 5分钟private final CountDownLatch cyclicBarrier= new CyclicBarrier(2);//设置屏障拦截的线程数为2//3.结果返回后进行回调,解除阻塞@Overridepublic void callback(AsynResponse response){    //我也到达屏障了,可以开门了    cyclicBarrier.await();}public Result getResult() throws ErrorCodeException {    // 1.异步调用    // 2.阻塞等待异步响应    try {        //我到达屏障了,还没开门,要等一等        cyclicBarrier.await(SECONDS_OF_WAIT_TIME, TimeUnit.SECONDS);    } catch (InterruptedException e) {        //TODO    }//4.超时或结果正确返回,对结果进行处理    return result;}

CountDownLatch和CyclicBarrier实现类似,区别是CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset重置,

所以CyclicBarrier能处理更为复杂的业务场景。在异步转同步中,计数器不会重用,所以使用CountDownLatch实现更适合。

6.LockSupport

LockSupport定义了一组公共静态方法,提供了最基本的线程阻塞和唤醒的方法。

private static long NANOS_OF_WAIT_TIME = 300000000L;// 等待时间 5分钟private final LockSupport lockSupport = new LockSupport();//3.结果返回后进行回调,解除阻塞@Overridepublic void callback(AsynResponse response){    lockSupport.unpark();}public Result getResult() throws ErrorCodeException {    // 1.异步调用    // 2.阻塞等待异步响应    try {        lockSupport.parkNanos(NANOS_OF_WAIT_TIME);    } catch (InterruptedException e) {        //TODO    }//4.超时或结果正确返回,对结果进行处理    return result;}

以上就是“Java中异步转同步的方法有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java中异步转同步的方法有哪些

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java中异步转同步的方法有哪些

今天小编给大家分享一下Java中异步转同步的方法有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、问题应用场景应用中通
2023-07-02

java异步转同步的方法是什么

Java中实现异步转同步的方法有多种,下面列举了几种常用的方法。使用CountDownLatch:CountDownLatch latch = new CountDownLatch(1);// 异步操作new Thread(() ->
2023-10-24

java同步方法有哪些

在Java中,有几种实现同步的方式:使用synchronized关键字:通过在方法前面加上synchronized关键字来实现同步。当一个线程进入synchronized方法时,其他线程需要等待,直到该线程执行完毕。使用synchroniz
2023-10-25

java同步和异步的区别有哪些

Java中同步(Synchronous)和异步(Asynchronous)的区别主要体现在程序的执行方式和处理结果上。1. 执行方式:同步代码按照顺序依次执行,一行代码执行完才能执行下一行代码;异步代码可以在某个操作进行的同时执行其他代码,
2023-08-09

java中有哪些线程同步的方法

java中有哪些线程同步的方法?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1.同步方法 即有synchronized关键字修饰的方法。 由于j
2023-05-30

java实现异步的方法有哪些

Java实现异步的方法有以下几种:1. 使用线程池:可以通过ExecutorService接口创建线程池,然后使用submit()或execute()方法提交任务进行异步执行。2. 使用CompletableFuture:Completab
2023-08-09

redis同步方法有哪些

Redis的同步方法有以下几种:1. RDB持久化:将内存中的数据转存到硬盘上的RDB文件中,通过设置Redis的持久化策略可以定期自动进行RDB持久化,也可以通过命令手动触发。2. AOF持久化:将Redis的写命令以日志的形式追加到AO
2023-08-24

kafka同步发送和异步发送有哪些异同点

Kafka的同步发送和异步发送方式有以下异同点:异同点:发送方式:同步发送和异步发送都是通过KafkaProducer发送消息到Kafka集群。阻塞:同步发送是阻塞的,即发送消息后会一直等待直到收到服务器的响应,因此发送消息的速度取决于
2023-10-27

java中实现多线程同步的方法有哪些

这篇文章将为大家详细讲解有关java中实现多线程同步的方法有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。为什么要线程同步因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既
2023-05-31

java异步调用的实现方法有哪些

在Java中,有以下几种方式可以实现异步调用:1. 使用Thread类:可以通过创建和启动一个新的线程来实现异步调用。这种方式比较底层,需要手动管理线程的生命周期和同步机制。2. 使用ExecutorService框架:Java提供了Exe
2023-08-12

java异步编程有哪些方式

本篇内容介绍了“java异步编程有哪些方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为什么需要异步?操作系统可以看作是个虚拟机(VM),
2023-06-15

Java实现多线程同步的方法有哪些

Java实现多线程同步的方法有以下几种:1. 使用synchronized关键字:通过在方法或代码块前加上synchronized关键字,可以确保同一时间只有一个线程可以执行该方法或代码块。2. 使用ReentrantLock类:该类是Ja
2023-08-14

ajax同步和异步的应用场景有哪些

Ajax异步请求的主要应用场景包括:1. 实时更新数据:可以通过Ajax异步请求来更新页面上的数据,如即时聊天、动态通知等。2. 提交表单数据:使用Ajax异步请求可以在不刷新整个页面的情况下提交表单数据,并获取服务器返回的结果。3. 加载
2023-09-13

java中异步和同步有什么区别

java中异步和同步有什么区别?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java的优点是什么1. 简单,只需理解基本的概念,就可以编写适合于各种情况的应用程序;2. 面向对
2023-06-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录