Notas de estudio de JAVA (subprocesos múltiples 4) - seguridad de subprocesos 3 (mecanismo de sincronización de subprocesos - Bloqueo)
Método 3: Bloqueo (bloqueo) (agregado después de JDK5.0)
El método para resolver el problema de la seguridad de subprocesos (mecanismo de sincronización) - la tercera forma de lograr la sincronización -> Bloquear (lock)
- A partir de JDK 5.0, Java proporciona un mecanismo de sincronización de subprocesos más potente: la sincronización se logra definiendo explícitamente un objeto de bloqueo de sincronización. Los bloqueos de sincronización se implementan mediante objetos Lock.
- La interfaz java.util.concurrent.locks.Lock es una herramienta para controlar el acceso a recursos compartidos por varios subprocesos.
El bloqueo proporciona acceso exclusivo a los recursos compartidos. Solo un subproceso puede bloquear el objeto de bloqueo a la vez, y el subproceso debe obtener el objeto de bloqueo antes de comenzar a acceder al recurso compartido. - La clase ReentrantLock implementa Lock, que tiene la misma simultaneidad y semántica de memoria que la sincronizada. Al implementar el control seguro para subprocesos, se usa más comúnmente ReentrantLock, que puede bloquear y liberar bloqueos explícitamente.
Preguntas de entrevista más comunes: ¿las similitudes y diferencias entre sincronizado y bloqueo?
Igual :
ambos pueden resolver el problema de seguridad del hilo
diferente :
- El mecanismo sincronizado libera automáticamente el monitor de sincronización después de ejecutar el código de sincronización correspondiente
- El bloqueo debe iniciar la sincronización manualmente (método lock()) y la sincronización final también debe implementarse manualmente (método unLock())
Orden de prioridad sugerido para los métodos síncronos:
Bloqueo → bloque de código síncrono (ya se ingresó al cuerpo del método y se asignaron los recursos correspondientes) → método síncrono (fuera del cuerpo del método)
LockTest (usando la implementación de la interfaz Runnable para implementar el mecanismo de sincronización de subprocesos Lock (lock))
class Windows6 implements Runnable{
private int ticket=100;
//1.实例化ReentrantLock
private ReentrantLock lock=new ReentrantLock();
@Override
public void run() {
try{
//2.调用上锁方法lock()
lock.lock();
while (true){
if (ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket);
ticket--;
}else {
break;
}
}
}finally {
//3.调用解锁方法unlock()
lock.unlock();
}
}
}
public class LockTest {
public static void main(String[] args) {
Windows6 windows = new Windows6();
Thread t1 = new Thread(windows);
Thread t2 = new Thread(windows);
Thread t3 = new Thread(windows);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
LockTest1 (usando el método de heredar la clase Thread para implementar el mecanismo de sincronización de hilos Lock (lock))
class Windows7 extends Thread{
private static int ticket=100;
//1.实例化ReentrantLock
private static ReentrantLock lock=new ReentrantLock();
@Override
public void run() {
try{
//2.调用上锁方法lock()
lock.lock();
while (true){
if (ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket);
ticket--;
}else {
break;
}
}
}finally {
//3.调用解锁方法unlock()
lock.unlock();
}
}
}
public class LockTest1 {
public static void main(String[] args) {
Windows7 windows1=new Windows7();
Windows7 windows2=new Windows7();
Windows7 windows3=new Windows7();
windows1.setName("窗口1");
windows2.setName("窗口2");
windows3.setName("窗口3");
windows1.start();
windows2.start();
windows3.start();
}
}