首页
学习
活动
专区
圈层
工具
发布

基本概念1 同步和异步2 阻塞和非阻塞3 5.死锁(Deadlock),饥饿(Starvation)和活锁(Livelock)

1 同步和异步 同步和异步关注的是消息通信机制 所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。就是由调用者主动等待这个调用的结果。...而异步则是相反,调用在发出之后,这个调用就会立即返回,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。...而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。...而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。...死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。

1.4K70

从代码层面优化系统性能应该怎么做?

在实际生产环境中,经常出现数据库死锁导致整个服务中断不可用。 数据库事务乱用,导致事务占用时间太长。 在实际生产环境中,服务器经常出现内存溢出和 CPU 时间被占满。...针对以上问题完全没有必要使用悲观锁的方式来进行防重,不仅对数据库本身造成极大的压力,同时也会把对于项目扩展性来说也是很大的扩展瓶颈,我们采用了三种方法来解决以上问题: 使用 Redis 来做分布式锁,Redis...使用主键防重方法,在方法的入口处使用防重表,能够拦截所有重复的订单,当重复插入时数据库会报一个重复错,程序直接返回。 使用版本号的机制来防重。...数据库事务占用时间过长 伪代码示例: ?...,处理完成回调应用程序器。

57130
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    浅谈网络中接口幂等性设计问题

    在接口调用时一般情况下都能正常返回信息不会重复提交,不过在遇见以下情况时可能就会出现问题,如: 微服务架构下,不同微服务间会有大量的基于 http,rpc 或者 mq 消息的网络通信。...如果超时了,微服务框架会进行重试; 用户交互的时候多次点击,无意地触发多笔交易; MQ消息中间件,消息重复消费; 第三方平台的接口(如:支付成功回调接口),因为异常也会导致多次异步回调; 其他中间件/应用服务根据自身的特性...通过Redis做分布式锁,只有当一个请求执行完成后,才能执行下个请求。 # Token 机制实现 通过 Token 机制实现接口的幂等性,这是一种比较通用性的实现方法。...具体流程步骤: 客户端先发送一个请求去获取 Token,服务端会生成一个全局唯一的 ID 作为 Token 保存在 Redis 中,同时把这个 ID 返回给客户端; 客户端第二次调用业务请求的时候必须携带这个...悲观锁在使用的过程中也是会发生死锁的。悲观锁是 通过锁表的方式实现的。

    83020

    Node中的事件循环和异步API

    多线程编程也因为编程中的死锁、状态同步等问题让开发人员头痛。 Node在两者之间给出了它的解决方案:利用单线程,远离多线程死锁、状态同步等问题;利用异步I/O,让单线程远离阻塞,以好使用CPU。...1.1 异步I/O 在Node中,JS是在单线程中执行的没错,但是内部完成I/O工作的另有线程池,使用一个主进程和多个I/O线程来模拟异步I/O。...当主线程发起I/O调用时,I/O操作会被放在I/O线程来执行,主线程继续执行下面的任务,在I/O线程完成操作后会带着数据通知主线程发起回调。...在进行系统调用时,从JS层传入的方法和参数都被封装在一个请求对象中,请求对象被放在线程池中等待执行。JS立即返回继续后续操作。...2.1 setTimeout()与setInterval() 这两个方法实现原理与异步I/O相似,只不过不用I/O线程池的参与。

    2.1K30

    一次 “慢” 请求引发的血案:从火焰图到缓存的性能调优之旅

    CPU 并没有在忙于计算,而是在忙于上下文切换和等待,这在火焰图上表现为函数耗时极长。四、一波未平,一波又起:并发死锁的幽灵找到了问题,修复方案似乎也很简单:缩小锁的粒度。...五、终极方案:从本地缓存到分布式缓存的升维这次死锁的经历让我们意识到,在复杂的系统中,仅靠优化锁的粒度是不够的,锁本身就是复杂性的来源。我们需要从根本上解决问题。...优化维度优化前 (本地内存缓存)优化后 (Redis 分布式缓存)缓存机制map[string]Rule + sync.MutexRedis HGET/HSET并发安全依赖开发者正确使用锁,易出错Redis...六、总结与反思这次惊心动魄的性能调优,像一本生动的教科书,让我对系统性能有了更深刻的理解:善用工具:从时序分析到火焰图,再到竞争检测,现代化的性能工具是我们在黑暗中航行的灯塔。...使用时必须慎之又慎,尽可能缩小其作用域,并警惕死锁风险。升维思考:当在一个维度(如优化锁)上反复遇到问题时,不妨跳出来,从更高的架构维度(如引入分布式缓存)去思考解决方案。

    19910

    论代码级性能优化变迁之路(一)

    2、在实际生产环境中,经常出现数据库死锁导致整个服务中断不可用。 3、数据库事务乱用,导致事务占用时间太长。 4、在实际生产环境中,服务器经常出现内存溢出和CPU时间被占满。...针对以上问题完全没有必要使用悲观锁的方式来进行防重,不仅对数据库本身造成极大的压力,同时也会把对于项目扩展性来说也是很大的扩展瓶颈,我们采用了三种方法来解决以上问题: 使用Redis来做分布式锁,Redis...使用主键防重方法,在方法的入口处使用防重表,能够拦截所有重复的订单,当重复插入时数据库会报一个重复错,程序直接返回。 使用版本号的机制来防重。...以任务的方式发送到专门的任务处理器处理,处理完成回调应用程序器。...甚至有些方法的入参和出参也要考虑打印出来。 在输入错误信息的时候,Exception不要以e.getMessage的方式打印出来。

    58220

    YashanDB连接池配置优化及多线程操作最佳实践

    使用连接池和多线程协同工作:在多线程操作中,各线程可以独立获取连接,执行数据库操作,从而充分利用连接池资源。在设计应用时,应确保对连接池的并发访问是线程安全的。3....利用异步非阻塞 I/O:YashanDB支持异步非阻塞 I/O 操作,可以使用回调函数处理查询结果,而无需阻塞线程执行,进一步提高系统的并发处理能力。4....事务管理和锁机制:在多线程执行数据库操作时,需注意控制并发事务对资源的竞争,YashanDB的悲观锁与乐观锁机制可以根据具体需求进行选择。在复杂场景中,合理的循环等待和死锁处理逻辑是必要的。...线程数优化:在高并发场景下,以CPU核心数为基准设置线程数,避免过多线程导致的上下文切换性能损失。3. 使用异步数据库操作:结合YashanDB的异步 API 处理多线程请求,尽量减少线程等待时间。...定期监控与调优:定期监控连接池的使用情况和数据库的性能指标,及时调整连接池参数和线程数配置。5. 加强事务管理:合理配置事务隔离级别与锁机制,以避免并发事务造成的资源竞争与死锁。

    20700

    【Redis在银行项目使用】

    Redis在银行项目中有以下几个应用场景: 缓存系统:银行项目通常需要处理大量的交易和查询,而这些操作可能需要从数据库中读取数据。...队列系统:银行项目中可能需要处理大量的异步任务,如交易回调通知、消息推送等。使用Redis的队列功能可以实现异步任务的处理,将任务添加到队列中,然后由后台的工作线程逐个消费任务。...使用Redis作为会话存储可以实现分布式会话管理,将用户的会话数据存储在共享的Redis集群中,实现会话的共享和跨客户端的访问。...Redis在银行项目中提供了高性能、高可靠性和高可用性的数据存储和处理方案,可以满足银行业务的各种需求。 项目实战 在项目中使用Redis,首先安装Redis服务器并启动。...('hash_key', 'field1') value2 = r.hget('hash_key', 'field2') print(value1.decode()) # 输出:value1 print

    26010

    Redis实现文件事件和时间事件的可扩展性,以及改进空间和建议

    定时器管理 :Redis使用时间轮或最小堆等数据结构来管理时间事件的触发时间,能够高效地处理大量的时间事件,保证事件的及时触发。...Redis也存在一些限制:Redis是单线程的 :Redis的事件循环是单线程的,因此在处理事件时无法充分利用多核处理器的性能。这就意味着在高并发的情况下,Redis的处理能力可能会受限。...引入异步事件处理机制,可以使得Redis能够在客户端请求或内部事件过多时进行流量控制,避免出现性能瓶颈。事件分发机制优化:Redis的事件分发机制是基于文件事件驱动的,采用I/O多路复用技术。...事件回调机制:引入事件回调机制,使得Redis能够在事件发生时通知相关的处理逻辑。通过回调机制,可以实现更灵活和高效的事件处理流程。...引入事件优先级调度机制,在处理客户端请求和内部事件时根据优先级进行调度,优先处理重要的事件。引入事件回调机制,实现更灵活和高效的事件处理流程。

    43161

    JVM进阶调优系列(7)JVM调优监控必备命令、工具集合|实用干货

    (s)FGC 从JVM启动到采样时old代(全gc)gc次数FGCT 从JVM启动到采样时old代(全gc)gc所用时间(s)GCT 从JVM启动到采样时gc用的总时间(s)1.4 jstack-线程死锁检测...load、内存、gc、线程的状态信息,并支持在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。...2.1.5 watch 实时监控方法返回值等这个不再赘述过多案例,官网给了非常详细的使用说明,此外还有实时修改logger日志级别、查看jvm信息、trace追踪方法调用耗时等。...项目在 GitHub上可以下载[https://github.com/chewiebug/GCViewer],可以非常直观地分析出有待调优改进地方。大家有空可以下载体验一下。...5、JVM进阶调优系列(1)类加载器原理一文讲透6、JAVA并发编程系列(13)Future、FutureTask异步小王子

    86520

    Golang+Redis可重入锁

    递归互斥锁解决了普通互斥锁不可重入的问题:如果函数先持有锁,然后执行回调,但回调的内容是调用它自己,就会产生死锁。...参考维基百科:可重入互斥锁 个人观点 在Go中应该很少会有这样的场景,互斥锁从字面上理解,应该不能接收重入,需要重入的场景也不应该考虑互斥锁。个人认为更好的解决方法是从设计的层面避免这种场景的出现。...因此,与基于redis的互斥锁不同,这篇文章仅仅是尝试在技术上的实现,在实际应用中应尽可能避免这样的场景出现 参考 功能 在基于redis的互斥锁(自动续期,自动重试)的基础上允许重入 实现的关键功能点...次(N>1)在线程内调用时会执行到此处) if (redis.call('HEXISTS', KEYS[1], ARGV[2]) == 1) then -- 调用次数递增 redis.call...次(N>1)在线程内调用时会执行到此处) if (redis.call('HEXISTS', KEYS[1], ARGV[2]) == 1) then -- 调用次数递增 redis.call

    2.3K00

    C#多线程开发-线程池03

    每次需要新的资源,只需从池中获取一个,不需要创建新的,当该资源不再被使用时,就将其返回到池中。 在.NET中,线程池可以使用ThreadPool类型,受.NET通用语言运行时(CLR)管理。...可以看到当第一次线程池中没有线程时,打印出来线程10不在线程中,当第二次在线程池中时,后面异步回调显示出来的结果就是再次调用的线程11。...BeginInvoke方法接受一个回调函数,该回调函数会在异步操作完成后会被调用,并且一个用户自定义的状态会传给该回调函数。...BeginInvoke立即返回结果,当线程池中的工作线程在执行异步操作时,仍允许继续其他工作,可以通过result对象的IsCompleted属性轮询结果。...这种就是基于事件的异步模式(EAP),就是启动一个异步操作然后订阅给不同的事件,这些事件在该操作执行时会被触发。 小寄语 人生短暂,我不想去追求自己看不见的,我只想抓住我能看的见的。

    1.2K20

    2021年大数据Flink(四十六):扩展阅读 异步IO

    ): 实现用来分发请求的AsyncFunction,用来向数据库发送异步请求并设置回调 获取操作结果的callback,并将它提交给ResultFuture 将异步I/O操作应用于DataStream...,一般在该方法中输出连接超时的错误日志,如果不重新该方法,连接超时后会抛出异常     @Override     public void timeout(String input, ResultFuture...;     } } /**  * 使用高性能异步组件vertx实现类似于连接池的功能,效率比连接池要高  * 1)在java版本中可以直接使用  * 2)如果在scala版本中使用的话,需要scala的版本是...在EventTime中,以watermark为边界,介于两个watermark之间的消息可以乱序,但是watermark和消息之间不能乱序,这样既认为在无序中又引入了有序,这样就有了与有序一样的开销。... 方法,该方法会向外部服务发起一个异步的请求,并注册回调 该回调会在异步请求成功返回时调用 AsyncCollector.collect 方法将返回的结果交给框架处理。

    1.6K20

    JavaScript专项算法题(4):异步

    异步 挑战一 sayHowdy 问题: 思考时间(现在暂时不需要编写代码):分析下方挑战一的代码,打印出来的结果会是怎样顺序的?Howdy先还是Partnah先?...挑战二 delayedGreet 问题: 构建delayedGreet函数,用于在3秒后打印“welcome”。...其有两个方法:start和reset。 start:当调用时,start会每秒调用一个回调函数(this.cb,在构造器中定义),作用于一个变量。这个变量每次被回调函数使用时总是当前的时间秒数。...第一次“滴答”(值为1)发生在最初的secondClock调用的1秒后; 第二次“滴答”(值为2)发生在最初的secondClock调用的2秒后; …… 第六十次“滴答”(值为60)发生在最初的secondClock...此返回函数仅会在其上次调用回调函数的interval毫秒后才会被再次调用回调函数。

    50020

    SpringBoot异步调用

    而异步调用指:程序在执行时,无需等待执行的返回值可继续执行后面的代码。显而易见,同步有依赖相关性,而异步没有,所以异步可并发执行,可提高执行效率,在相同的时间做更多的事情。...题外话:除了异步、同步外,还有一个叫回调。其主要是解决异步方法执行结果的处理方法,比如在希望异步调用结束时返回执行结果,这个时候就可以考虑使用回调机制。...Async异步调用 在SpringBoot中使用异步调用是很简单的,只需要使用@Async注解即可实现方法的异步调用。 注意:需要在启动类加入@EnableAsync使异步调用@Async注解生效。...调用的异步方法,不能为同一个类的方法,简单来说,因为Spring在启动扫描时会为其创建一个代理类,而同类调用时,还是调用本身的代理类的,所以和平常调用是一样的。...主要就是通过Future进行异步回调。

    1.4K30

    C#异步使用要点(翻译)

    异步操作时需要注意的要点 1.使用异步方法返回值应当避免使用void 在使用异步方法中最好不要使用void当做返回值,无返回值也应使用Task作为返回值,因为使用void作为返回值具有以下缺点 无法得知异步函数的状态机在什么时候执行完毕...void,所以在调用此方法时无法捕捉异常,使得进程崩溃 throw new Exception("异常了"); await Task.Run(() => { }); } 应该将异步函数返回...类中有一个接收回调函数的FireAndForget方法,该方法在某个时候执行调用 下面这个错误例子将强制调用者要么阻塞要么使用async void异步方法 public class BackgroundQueue...BackgroundQueue.FireAndForget(async () => { await httpClient.GetAsync("http://pinger/api/1"); }); } 所以应该构建一个回调异步方法的重载...,在最后,GetOrAdd()可能并行多次来执行缓存回调,这可能导致启动多次昂贵的计算 可以使用async lazy模式来取代多次执行回调问题 public class PersonController

    3.8K50

    使用异步操作时的注意要点(翻译)

    异步操作时需要注意的要点 1.使用异步方法返回值应当避免使用void 在使用异步方法中最好不要使用void当做返回值,无返回值也应使用Task作为返回值,因为使用void作为返回值具有以下缺点 无法得知异步函数的状态机在什么时候执行完毕...void,所以在调用此方法时无法捕捉异常,使得进程崩溃 throw new Exception("异常了"); await Task.Run(() => { }); } ☑️应该将异步函数返回...void 假如有BackgroudQueue类中有一个接收回调函数的FireAndForget方法,该方法在某个时候执行调用 ❌下面这个错误例子将强制调用者要么阻塞要么使用async void异步方法...async () => { await httpClient.GetAsync("http://pinger/api/1"); }); } ☑️所以应该构建一个回调异步方法的重载...这种方法,在最后,GetOrAdd()可能并行多次来执行缓存回调,这可能导致启动多次昂贵的计算 ☑️可以使用async lazy模式来取代多次执行回调问题 public class PersonController

    5K20

    基于 Redis 实现高级限流器及其在队列任务处理中的应用

    ::funnel 返回的是 ConcurrencyLimiter 限流器对应的构建器实例,然后我们通过 limit 方法指定并发请求上限,再通过 then 方法定义两个回调函数,第一个回调执行的是未触发并发上限时的正常业务逻辑...then 方法传入的第二个回调。...如果获取锁成功,意味着还没有触发请求上限,则执行上一层构建器 then 方法传入的第一个回调函数。...('HGET', KEYS[1], 'start') and ARGV[1] redis.call('HGET', KEYS[1], 'end') then return {...可以看出,在 block 方法中获取锁成功并执行回调函数处理请求后,并没有重置剩余可用槽位和当前请求数统计,所以目前而言,这个限流器的功能和上篇教程实现的是一样的,如果触发请求上限,只能等到时间窗口结束才能继续发起请求

    1.8K10
    领券