La palabra clave synchronized en Java controla el acceso a los recursos compartidos entre varios subprocesos. Garantiza que sólo un hilo pueda ejecutar un bloque o método sincronizado a la vez, evitando interferencias entre hilos y asegurando la coherencia de la memoria.
Utilización
La palabra clave synchronized puede aplicarse a métodos o bloques dentro de métodos. Cuando un método o bloque se declara como sincronizado, se obtiene un bloqueo sobre el objeto especificado, y se bloquea el acceso de otros hilos al código sincronizado hasta que se libere el bloqueo.
Syntax
Método sincronizado
public synchronized voidsynchronizedMethod(){// method code}Con la tecnología de
Bloque sincronizado
publicvoidmethod(){synchronized(object){// synchronized code}}Con la tecnología de
object: El objeto sobre el que sincronizar. Suele ser la instancia actual (this) o un objeto concreto.
Ejemplos
Ejemplo 1: Método sincronizado
publicclassCounter{private int count =0;public synchronized voidincrement(){
count++;}public int getCount(){return count;}publicstaticvoidmain(String[] args){
Counter counter =newCounter();// Create multiple threads to increment the counter
Thread t1 =newThread(()-> counter.increment());
Thread t2 =newThread(()-> counter.increment());
t1.start();
t2.start();try{
t1.join();
t2.join();}catch(InterruptedException e){
e.printStackTrace();}
System.out.println("Final count: "+ counter.getCount());}}Con la tecnología de
En este ejemplo, el método increment está sincronizado, lo que garantiza que sólo un hilo puede incrementar el contador a la vez, evitando condiciones de carrera.
Ejemplo 2: Bloque sincronizado
publicclassSynchronizedBlockExample{private final Object lock =newObject();private int count =0;publicvoidincrement(){synchronized(lock){
count++;}}public int getCount(){return count;}publicstaticvoidmain(String[] args){
SynchronizedBlockExample example =newSynchronizedBlockExample();// Create multiple threads to increment the counter
Thread t1 =newThread(()-> example.increment());
Thread t2 =newThread(()-> example.increment());
t1.start();
t2.start();try{
t1.join();
t2.join();}catch(InterruptedException e){
e.printStackTrace();}
System.out.println("Final count: "+ example.getCount());}}Con la tecnología de
Este ejemplo utiliza un bloque sincronizado para controlar el acceso a la variable count. El objeto de bloqueo garantiza que sólo un hilo pueda ejecutar el bloque sincronizado a la vez.
Consejos y buenas prácticas
Minimizar el Código Sincronizado: Mantén los bloques sincronizados lo más cortos posible para reducir la contención y mejorar el rendimiento.
Utiliza Objetos Finales: Cuando utilices bloques sincronizados, utiliza objetos finales como bloqueos para garantizar la coherencia.
Evita la Sincronización Anidada: Los bloques sincronizados anidados pueden provocar bloqueos. Evítalos o utilízalos con precaución.
Utiliza Colecciones Concurrentes: Para una sincronización compleja, considera la posibilidad de utilizar colecciones concurrentes del paquete java.util.concurrent, como ConcurrentHashMap, que proporcionan sincronización incorporada.
Palabra clave volátil: Para las variables a las que acceden varios subprocesos pero que no requieren una sincronización compleja, considera la posibilidad de utilizar la palabra clave volatile para garantizar la visibilidad.
Seguridad de la rosca: Asegúrate siempre de que los recursos compartidos están correctamente sincronizados para mantener la seguridad de los hilos y evitar la corrupción de datos.
Métodos estáticos sincronizados: Sincroniza los métodos estáticos para imponer el acceso sincronizado a nivel de clase, garantizando que sólo un hilo pueda ejecutar el método estático en todas las instancias.
publicstatic synchronized voidstaticMethod(){// method code}Con la tecnología de
Reentrada: Los bloqueos intrínsecos de Java son reentrantes, lo que significa que si un hilo tiene un bloqueo, puede adquirirlo de nuevo sin bloquearse.
La palabra clave
synchronizeden Java controla el acceso a los recursos compartidos entre varios subprocesos. Garantiza que sólo un hilo pueda ejecutar un bloque o método sincronizado a la vez, evitando interferencias entre hilos y asegurando la coherencia de la memoria.Utilización
La palabra clave
synchronizedpuede aplicarse a métodos o bloques dentro de métodos. Cuando un método o bloque se declara como sincronizado, se obtiene un bloqueo sobre el objeto especificado, y se bloquea el acceso de otros hilos al código sincronizado hasta que se libere el bloqueo.Syntax
Método sincronizado
Bloque sincronizado
object: El objeto sobre el que sincronizar. Suele ser la instancia actual (this) o un objeto concreto.Ejemplos
Ejemplo 1: Método sincronizado
En este ejemplo, el método
incrementestá sincronizado, lo que garantiza que sólo un hilo puede incrementar el contador a la vez, evitando condiciones de carrera.Ejemplo 2: Bloque sincronizado
Este ejemplo utiliza un bloque sincronizado para controlar el acceso a la variable
count. El objeto de bloqueo garantiza que sólo un hilo pueda ejecutar el bloque sincronizado a la vez.Consejos y buenas prácticas
java.util.concurrent, comoConcurrentHashMap, que proporcionan sincronización incorporada.volatilepara garantizar la visibilidad.