Bloquear
Tabla de contenido
1. Dos puertos de bloqueo
- Bloqueo: admite reentrante, equidad y otras reglas de bloqueo, clases de implementación: ReentrantLock, ReadLock, WriteLock
- ReadWriteLock: la interfaz define un bloqueo compartido por lectores y bloqueos exclusivos para escritores. Clase de implementación: ReentrantReadWriteLock
2. Bloqueo reentrante
- Bloqueo no reentrante: es decir, el hilo se bloqueará al solicitar el bloqueo que ya tiene
- Bloqueo reentrante: es decir, el hilo puede entrar en el bloque de código de sincronización del bloqueo que ya tiene
Código de prueba
public class ReentrantLockTest {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
lock.lock();
System.out.println("加锁次数" + i);
}
for (int i = 0; i < 10; i++) {
try {
System.out.println("解锁次数" + i);
} finally {
lock.unlock();
}
}
}
}
Resultados de la prueba
加锁次数0
加锁次数1
加锁次数2
加锁次数3
加锁次数4
加锁次数5
加锁次数6
加锁次数7
加锁次数8
加锁次数9
解锁次数0
解锁次数1
解锁次数2
解锁次数3
解锁次数4
解锁次数5
解锁次数6
解锁次数7
解锁次数8
解锁次数9
3. Bloqueo de lectura y escritura
- Ambos pueden leer al mismo tiempo, pero no pueden escribir mientras leen,
- No puede escribir al mismo tiempo, no puede leer mientras escribe
Código de prueba
public class ReadWriteLockTest {
//要访问的对象
private Map<String, String> map = new HashMap<>();
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//读锁
ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
//写锁
ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
public String get(String key) {
try {
readLock.lock();
System.out.println(Thread.currentThread().getName() + "线程读锁已加锁");
Thread.sleep(3000);
return map.get(key);
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
readLock.unlock();
System.out.println(Thread.currentThread().getName() + "线程读锁已解锁");
}
}
public void put(String key, String value) {
try {
readLock.lock();
System.out.println(Thread.currentThread().getName() + "线程写锁已加锁");
Thread.sleep(3000);
map.put(key, value);
} catch (Exception e) {
e.printStackTrace();
} finally {
readLock.unlock();
System.out.println(Thread.currentThread().getName() + "线程写锁已解锁");
}
}
public static void main(String[] args) {
ReadWriteLockTest readWriteLockTest = new ReadWriteLockTest();
readWriteLockTest.put("key1", "value1");
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
readWriteLockTest.get("key1");
}
}).start();
}
}
}
Resultados de la prueba
main线程写锁已加锁
main线程写锁已解锁
Thread-0线程读锁已加锁
Thread-1线程读锁已加锁
Thread-2线程读锁已加锁
Thread-3线程读锁已加锁
Thread-4线程读锁已加锁
Thread-0线程读锁已解锁
Thread-3线程读锁已解锁
Thread-4线程读锁已解锁
Thread-1线程读锁已解锁
Thread-2线程读锁已解锁
Conclusión Los bloqueos de lectura se ejecutan después de los bloqueos de escritura