JAVA日常学习----锁

1.synchronized锁

  • synchronized锁可以加在方法和代码块上。
  • 当一个线程正在访问一个对象的synchronized方法,那么其他线程不能访问该对象的其他synchronized方法。

  • 当一个线程正在访问一个对象的synchronized方法,那么其他线程能访问该对象的非synchronized方法。

  • 如果一个线程A需要访问对象object1的synchronized方法fun1,另外一个线程B需要访问对象object2的synchronized方法fun1,即使object1和object2是同一类型),也不会产生线程安全问题,因为他们访问的是不同的对象,所以不存在互斥问题。

  • 对于synchronized方法或者synchronized代码块,当出现异常时,JVM会自动释放当前线程占用的锁,因此不会由于异常导致出现死锁现象。
  • synchronized释放锁时机:代码执行完毕 , 发生异常。

2.Lock锁

JDK1.5之后并发包提供了Lock接口以及其实现类来实现锁功能。

位于java.util.concurrent.locks包下。

lock接口的实现类:ReentrantLock , ReentrantReadWriteLock.ReadLock , ReentrantReadWriteLock.WriteLock

lock接口提供了synchronized关键字不具有的特性:

lock接口额外特性
特性描述
尝试非阻塞获得锁当前线程尝试获取锁,如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁
获得锁,能够被中断尝试获得锁的线程能够响应中断,被中断的线程会抛出终端异常,同时释放锁
获得锁,指定等待时间等待指定时间去获得锁,如果超时则返回

 

2.1 lock获取锁

lock接口提供了四种方法获取锁:

  • Lock()方法:尝试获取锁,如果锁被其他线程获得,则等待。lock方法需要主动释放锁,发生异常时不会主动释放锁,所以一般采用如下方式使用lock()
Lock lock = ...;
lock.lock();
try{
    //处理任务
}catch(Exception ex){
 
}finally{
    lock.unlock();   //释放锁
}

 

  • tryLock()方法:这个方法是有返回值的,方法会尝试获得锁,获得成功则返回true,失败返回false。无论如何,该方法都会立即返回。
  • tryLock(long time, TimeUnit unit)方法:与tryLock类似,如果在指定的时间内拿到锁,则返回true,否则返回false。
  • LockInterruptibly():当通过这个方法获得锁时,如果线程正在等待获得锁,这个线程可以被中断,即终端线程的等待状态。比如线程A得到了锁,线程B调用LockInterruptibly()等待锁,则此时可以调用B.interrupt()方法中断B等待获得锁。另外Interrupt()方法只能中断阻塞中的线程,不能中断执行中的线程。
  • ReentrantLock:可重入锁

2.2 ReadWriteLock

ReadWriteLock是一个接口,其中声明了两个方法:Lock readLock(),Lock writeLock(),其中一个用来获取读锁,一个用来回去写锁,可以将读写分离,使多个线程可以同时进行操作。

实现接口的类:ReentrantReadWriteLock

读写锁可以支持多个线程同时进行读操作,但只能有一个线程进行写操作。

如果一个线程申请了读锁,另一给线程申请写锁,则会等待知道读锁释放。

如果一个线程申请了写锁,另一个线程不管申请读锁还是写锁,都会等待直到写锁释放。

2.3 lock和synchronized

  • lock是接口,sychronized是关键字
  • sychronized在发生异常时会释放锁,不会造成死锁。lock在发生异常时不会释放锁,会造成死锁,所以需要在finally中进行释放。
  • lock能够响应中断,sychronized不能响应中断,等待的线程会一直等待下去。
  • lock方法可以知道有没有成功获得锁。
  • lock可以提高多个线程进行读操作的效率

3 锁相关概念

3.1 可重入锁

ReentrantLock和sychronized都是可重入锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提锁对象得是同一个对象或者class),不会因为之前已经获取过还没释放而阻塞。可重入锁的一个优点是可一定程度避免死锁。

3.2 可中断锁

3.3 公平锁

3.4 重量级锁

重量锁的同步成本很高,包括系统调用引起的内核态和用户态切换、线程阻塞造成的线程切换等。

3.5 自旋锁

目的:降低线程切换成本。

当线程竞争锁失败时,打算阻塞自己,这时候步进行阻塞,而是自旋(进入一个空的有限for循环),并同时竞争锁。如果自旋结束之前获得了锁,那么获得锁成功,否则阻塞自己。

适用于锁的持有时间短,或者锁的持有时间长但是竞争不激烈的场景。

缺点:

单核处理器上,不存在实际的并行,当前线程不阻塞自己的话,已获得锁的线程就不能执行,锁永远不会释放,此时不管自旋多久都是浪费;进而,如果线程多而处理器少,自旋也会造成不少无谓的浪费。 

自旋锁要占用CPU,如果是计算密集型任务,这一优化通常得不偿失,减少锁的使用是更好的选择。

如果锁竞争的时间比较长,那么自旋通常不能获得锁,白白浪费了自旋占用的CPU时间。这通常发生在锁持有时间长,且竞争激烈的场景中,此时应主动禁用自旋锁。

3.6 自适应自旋锁

如果线程通过自旋获得了锁,则增加自旋时间。如果没有通过自旋获得锁,则减少自旋时间。

适用于自适应自旋假定不同线程持有同一个锁对象的时间基本相当,竞争程度趋于稳定,因此,可以根据上一次自旋的时间与结果调整下一次自旋的时间

缺点

然而,自适应自旋也没能彻底解决该问题,如果默认的自旋次数设置不合理(过高或过低),那么自适应的过程将很难收敛到合适的值

3.7 轻量级锁

如果锁竞争激烈,我们不得不依赖于重量级锁,让竞争失败的线程阻塞;如果完全没有实际的锁竞争,那么申请重量级锁都是浪费的。轻量级锁的目标是,减少无实际竞争情况下,使用重量级锁产生的性能消耗,包括系统调用引起的内核态与用户态切换、线程阻塞造成的线程切换等。

缺点:如果锁竞争激烈,那么轻量级将很快膨胀为重量级锁,那么维持轻量级锁的过程就成了浪费

3.8 偏向锁

如果不仅仅没有实际竞争,自始至终,使用锁的线程都只有一个,那么,维护轻量级锁都是浪费的。偏向锁的目标是,减少无竞争且只有一个线程使用锁的情况下,使用轻量级锁产生的性能消耗。轻量级锁每次申请、释放锁都至少需要一次CAS,但偏向锁只有初始化时需要一次CAS。

“偏向”的意思是,偏向锁假定将来只有第一个申请锁的线程会使用锁(不会有任何线程再来申请锁),因此,只需要在Mark Word中CAS记录owner(本质上也是更新,但初始值为空),如果记录成功,则偏向锁获取成功,记录锁状态为偏向锁,以后当前线程等于owner就可以零成本的直接获得锁;否则,说明有其他线程竞争,膨胀为轻量级锁

偏向锁无法使用自旋锁优化,因为一旦有其他线程申请锁,就破坏了偏向锁的假定。


缺点:同样的,如果明显存在其他线程申请锁,那么偏向锁将很快膨胀为轻量级锁。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Java技术性,挑选MySQL作为后台系统。系统主要包含对客服聊天管理、字典表管理、公告信息管理、金融工具管理、金融工具收藏管理、金融工具银行卡管理、借款管理、理财产品管理、理财产品收藏管理、理财产品银行卡管理、理财银行卡信息管理、银行卡管理、存款管理、银行卡记录管理、取款管理、转账管理、用户管理、员工管理等功能模块。 文中重点介绍了银行管理的专业技术发展背景和发展状况,随后遵照软件传统式研发流程,最先挑选适用思维和语言软件开发平台,依据需求分析报告模块和设计数据库结构,再根据系统功能模块的设计制作系统功能模块图、流程表和E-R图。随后设计架构以及编写代码,并实现系统能模块。最终基本完成系统检测和功能测试。结果显示,该系统能够实现所需要的作用,工作状态没有明显缺陷。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。进入银行卡列表,管理员可以进行查看列表、模糊搜索以及相关维护等操作。用户进入系统可以查看公告和模糊搜索公告信息、也可以进行公告维护操作。理财产品管理页面,管理员可以进行查看列表、模糊搜索以及相关维护等操作。产品类型管理页面,此页面提供给管理员的功能有:新增产品类型,修改产品类型,删除产品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值