Java之锁(持续更新)

前言

java锁一般配合多线程进行使用,需要了解多线程的可点击下面链接
多线程技术

Synchronize

Synchronize基础知识

对于普通方法的同步,锁是当前实例对象。
对于静态方法的同步,锁是当前类的Class对象。
对于同步方法块,锁是Synchronized括号里配置的对象。

非公平锁、锁升级、可重入锁、JVM级别且隐式获得释放锁。
同步阻塞,使用的是悲观并发策略。

Synchronized 在jvm的底层实现

1、锁竞争候选者(OnDeck),并发情况下,
大部分线程都处在ContentionList ,JVM 会将一部分线程移动到 EntryList 中作为候选竞争线程。
2、Owner 线程会在 unlock 时,将 ContentionList 中的部分线程迁移到 EntryList 中,并指定EntryList 中的某个线程为 OnDeck 线程。
3、Owner 线程并不直接把锁传递给 OnDeck 线程,而是把锁竞争的权利交给 OnDeck,
OnDeck 需要重新竞争锁
4、OnDeck 线程获取到锁资源后会变为 Owner 线程,而没有得到锁资源的仍然停留在 EntryList中。如果 Owner 线程被 wait 方法阻塞,则转移到 WaitSet 队列中,直到某个时刻通过 notify或者 notifyAll 唤醒,会重新进去 EntryList 中。
5、处于 ContentionList、EntryList、WaitSet 中的线程都处于阻塞状态。
6、Synchronized 是非公平锁。 Synchronized 在线程进入 ContentionList 时,等待的线程会先尝试自旋获取锁,如果获取不到就进入 ContentionList,这明显对于已经进入队列的线程是不公平的,还有一个不公平的事情就是自旋获取锁的线程还可能直接抢占 OnDeck 线程的锁资源。

Synchronized 核心组件
1.Wait Set:哪些调用 wait 方法被阻塞的线程被放置在这里;
2.Contention List:竞争队列,所有请求锁的线程首先被放在这个竞争队列中;
3.Entry List:Contention List 中那些有资格成为候选资源的线程被移动到 Entry List 中;
4.OnDeck:任意时刻,最多只有一个线程正在竞争锁资源,该线程被成为 OnDeck࿱

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果在 Java 中手动管理事务,并且不正确地使用事务,可能会导致长事务锁表。这是因为在事务未正确提交或回滚时,数据库表上的锁将一直保持。这将阻止其他事务对该表进行操作,并可能导致性能问题和死锁。为了避免这种情况,应该及时提交或回滚事务,并使用合适的隔离级别。 ### 回答2: Java中的事务是一种用于确保数据库操作的原子性、一致性、隔离性和持久性的机制。手动事务是指在代码中通过编程方式控制事务的开始和结束,例如使用JDBC的beginTransaction()和commit()方法。 手动事务的使用需要谨慎,因为如果事务的操作时间过长,可能导致长事务锁表的问题。长事务指的是事务持续执行的时间过长,导致其他会话无法访问或修改被锁定的资源。 长事务锁表的主要原因是事务在对某个表进行更新操作时,会获取并持有该表的锁,直到事务提交或回滚。如果事务执行的时间过长,其他会话就无法对同一表进行任何操作,从而导致阻塞。 为了避免长事务锁表问题,可以采取以下几种措施: 1. 尽量减少事务操作的时间,尽快释放锁定的资源。可以对事务中的操作进行性能优化,并使用合适的索引和查询优化技巧,以减少数据库操作的时间。 2. 合理选择事务的隔离级别。不同的隔离级别会对资源锁定的行为产生不同的影响。例如,使用Read Committed隔离级别可以减少锁定的范围,从而降低锁表的概率。 3. 控制事务的粒度。如果一个事务需要对多个表进行操作,可以将事务分为多个较小的事务,从而减少每个事务的执行时间和对资源的锁定。 4. 合理设置数据库的参数。例如,可以调整数据库的锁超时时间以及最大并发连接数等参数,以适应实际需求。 总之,虽然手动事务在控制数据库操作的同时提供了更大的灵活性,但需要在使用时注意事务的执行时间,避免长事务锁表问题的发生。同时也可以结合数据库的优化策略和调整参数,提高系统对长事务的容忍度。 ### 回答3: Java中的事务是一种用来管理数据库操作的机制,可以保证数据的一致性和完整性。但是,在手动管理事务的过程中,如果事务执行的时间过长,就可能会出现长事务锁表的问题。 当一个事务开始执行时,会获取所需的锁,以保证事务的原子性和一致性。在手动事务中,当开启一个事务后,所有的数据库操作都处于同一个事务中,直到事务提交或回滚。 如果在事务中执行的操作非常复杂,或者在事务中执行的查询、更新等操作的数据量非常大,就可能导致事务执行时间过长。这样的话,其他需要访问被锁定资源的操作只能等待事务完成才能继续执行,从而导致长事务锁定表。 长事务锁表的问题可以通过以下几种方式来解决或缓解: 1. 优化事务操作:尽量减少事务执行的时间,可以考虑对复杂的操作进行优化,减少数据库的访问次数,降低锁定表的时间。 2. 拆分事务:将一个大的事务拆分成多个较小的事务,这样可以减少每个事务的执行时间,从而降低锁定表的时间。 3. 设置合适的隔离级别:在Java中,通过设置合适的事务隔离级别,可以在一定程度上降低锁定表的时间。可以根据需求选择适合的隔离级别,如读未提交、读已提交、可重复读、串行化等。 4. 合理规划事务边界:在应用程序设计中,合理规划事务的边界也是可以帮助缓解长事务锁表问题的。根据实际需求,将一次操作中可能发生的锁表问题拆分成多次操作,尽量减少长事务的出现。 总之,手动事务的长时间执行可能导致长事务锁表问题。为了解决这个问题,可以对事务操作进行优化,拆分事务,设置合适的隔离级别,合理规划事务边界等。这些措施可以帮助缓解长事务锁表问题,提高系统的性能和响应速度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值