Java-多线程并发05锁的概述

悲观锁:对外界修改数据保持悲观的态度(保守)。认为数据很容易被他的线程修改,所以在修改前加锁,在整个数据处理的过程中,对数据保持加锁的状态。

               实现依靠数据库提供的锁,在数据记录操作前加排他锁。

              如果获取锁失败说明数据正在修改,线程等待或抛出异常。

             如果获取锁成功就对数据进行操作,然后提交事务后释放排他锁。

 

乐观锁:对外界修改数据保持乐观的态度,认为数据不会发生冲突。不会再访问记录之前加排他锁,而是在数据提交更新时候检查是否冲突。

              乐观锁不会使用数据库提供的锁机制。一般在表中添加version字段或者使用业务状态来实现。乐观锁直到提交才锁定,不会产生死锁现象。

 

公平锁:ReentrantLock

    ReentrantLock  pairLock = new ReentrantLock(true);

按请求锁的先后时间顺序来分配锁。

 

非公平锁:

ReentrantLock pairLock = new ReentrantLock(false);

运行时闯入,不一定先来先得。

 

在没有公平性需求的前提下使用非公平锁,公平锁会带来性能消耗

 

独占锁:悲观锁。只有一个线程可以得到锁。

    ReentrantLock

共享锁:乐观锁。可以多个线程同时持有锁。

    读写锁 ReadWriteLock 

 

可重入锁:只要该线程获取了该锁,可以无限次数(严格来说有限)进入被该锁锁住的代码。

     Synchronized内置锁是可重入锁。

     原理是通过一个内部的线程标识维护

 

自旋锁:当前线程获取锁时,如果发现锁已经被其它线程占有,不会马上阻塞自己,在不放弃CPU使用权的情况下,多次尝试获取(默认10)。

               如果仍然没有获取锁线程才会被挂起。 

               使用CPU时间换取线程阻塞和调度的开销,但是也有可能仍然没有获取到白白浪费时间。

 

posted @ 2021-04-06 11:00  NobodyHero  阅读(43)  评论(0编辑  收藏  举报