StampedLock java1.8 fornece melhor desempenho que ReadWriteLock.
Bloqueio otimista
O bloqueio otimista é uma idéia otimista, ou seja, leia mais e escreva menos e encontre gravações simultâneas 可能性低
(não sem, por isso também precisa ser bloqueado, o que é diferente da leitura otimista sem bloqueio). Toda vez que vou buscar dados, acho que outros Ele não será modificado e, portanto, não será bloqueado, mas quando for atualizado, será avaliado se outras pessoas atualizaram esses dados durante esse período. Faça a primeira leitura da corrente ao escrever 版本号
e adicione a operação de bloqueio (compare com o número da versão anterior , Se for o mesmo, atualize), se falhar, repita a operação de leitura, comparação e gravação.
O 乐观锁
básico em java é realizado por meio de CAS
operações.O CAS é uma operação atômica de atualização.Compara se o valor atual é o mesmo que o valor recebido.Se for o mesmo, ele é atualizado, caso contrário, falha.
Bloqueio pessimista
Um bloqueio pessimista é um pensamento pessimista, ou seja, pensando que há muita escrita e, ao escrever simultaneamente 可能性高
, toda vez que você obtém os dados, você acha que outras pessoas o modificam; portanto, toda vez que você lê e escreve dados, você os bloqueia, para que outras pessoas queiram ler e escrever isso Os dados serão bloqueados até que o bloqueio seja obtido.java中的悲观锁就是Synchronized
final StampedLock sl = new StampedLock();
/**
* 悲观读锁
* 与ReadWriteLock的读锁相似
* 允许多个线程进行读操作
* 与写锁互斥
**/
//获取悲观锁
long stamp = sl.readLock();
try {
//。。。。
}finally {
sl.unlockRead(stamp);
}
/**
* 写锁
* 与ReadWriteLock的写锁相似
* 只允许一个线程进行写操作
* 与读锁互斥
**/
//获取写锁
long stamp1 = sl.writeLock();
try{
//。。。
}finally {
//释放写锁
sl.unlockWrite(stamp1);
}
/**
* 乐观读锁升级为悲观读
* 锁的严苛程度变强叫做升级,反之叫做降级
**/
//获取乐观锁
long stamp = sl.tryOptimisticRead();
//判断执行读操作期间,是否存在写操作,如果存在则sl.validate返回false
if (!sl.validate(stamp)){
//升级为悲观锁
stamp = sl.readLock();
try{
//。。。
}finally {
//释放悲观读锁
sl.unlockRead(stamp);
}
Gramática
final StampedLock sl = new StampedLock();
/**
* 悲观读锁
* 与ReadWriteLock的读锁相似
* 允许多个线程进行读操作
* 与写锁互斥
**/
//获取悲观锁
long stamp = sl.readLock();
try {
//。。。。
}finally {
sl.unlockRead(stamp);
}
/**
* 写锁
* 与ReadWriteLock的写锁相似
* 只允许一个线程进行写操作
* 与读锁互斥
**/
//获取写锁
long stamp1 = sl.writeLock();
try{
//。。。
}finally {
//释放写锁
sl.unlockWrite(stamp1);
}
/**
* 乐观读锁升级为悲观读
* 锁的严苛程度变强叫做升级,反之叫做降级
**/
//获取乐观锁
long stamp = sl.tryOptimisticRead();
//判断执行读操作期间,是否存在写操作,如果存在则sl.validate返回false
if (!sl.validate(stamp)){
//升级为悲观锁
stamp = sl.readLock();
try{
//。。。
}finally {
//释放悲观读锁
sl.unlockRead(stamp);
}
A leitura otimista fornecida pelo StampedLock permite que um thread adquira um bloqueio de gravação, o que significa que nem todas as operações de gravação estão bloqueadas.
A leitura otimista não é o mesmo que o bloqueio otimista.A operação da leitura otimista é livre de bloqueios.A leitura otimista pensa que não haverá operação de gravação durante a leitura.
Exemplos
import java.util.concurrent.locks.StampedLock;
/**
* 悲观锁乐观锁
**/
public class Point {
private int x;
private int y;
final StampedLock sl = new StampedLock();
//计算到原点的距离
int distanceFromOrigin() throws Exception{
//乐观锁
long stamp = sl.tryOptimisticRead();
//读入局部变量,读的过程数据可能被修改
int curX = x;
int curY = y;
//判断执行读操作期间,是否存在写操作,如果存在则sl.validate返回false
if (!sl.validate(stamp)){
//升级为悲观锁
stamp = sl.readLock();
try{
curX = x;
curY = y;
}finally {
//释放悲观读锁
sl.unlockRead(stamp);
}
}
return (int)Math.sqrt(curX*curX + curY*curY);
}
}
StampedLock
Ele suporta três写锁
modos: ,悲观读
e乐观读
.- Permita que vários threads adquiram bloqueios otimistas e bloqueios de leitura pessimistas simultaneamente.
- Apenas um segmento pode adquirir o bloqueio de gravação
写锁
e悲观读锁
sim互斥
. - Ao usar StampedLock, você não deve chamar a operação de interrupção.Se precisar oferecer suporte à função de interrupção, use
可中断的悲观读锁
readLockInterruptibly()
e escreva a travawriteLockInterruptibly()
. - Após o sucesso
写锁
e悲观读锁
bloqueado no StampedLock , será返回一个stamp
; então解锁
, você precisará passar issostamp
. - StampedLock
不支持重入
(suporte a ReadWriteLock). - Os bloqueios de leitura e gravação pessimistas do StampedLock não suportam variáveis de condição.
- StampedLock suporta downgrade de bloqueio (por meio do método tryConvertToReadLock ()) e atualização (por meio do método tryConvertToWriteLock ()), mas é recomendável que você o use com cuidado.
Bloqueio otimista no banco de dados
- Adicione uma
版本号
versão do campo numérico na tabela . - Sempre que a tabela é atualizada, o campo da versão é incrementado em 1.
- Ao modificar os dados, use a chave primária e a versão como condições de modificação,
version一致
elas serão modificadas成功
. - Se a modificação falhar,
主键查询获取最新数据
execute a modificação novamente.