¿Cuál es la diferencia entre sincronizar un método estático y uno no estático en Java? ¿Alguien puede explicarlo con un ejemplo? ¿También hay alguna diferencia en sincronizar un método y sincronizar un bloque de código?diferencia entre sincronizar un método estático y un método no estático
Respuesta
Intentaré y agregaré un ejemplo para dejarlo más claro.
Como se ha mencionado, sincronizado en Java es una implementación del concepto Monitor. Cuando marca un bloque de código como sincronizado utiliza un objeto como parámetro. Cuando un hilo de ejecución llega a dicho bloque de código, primero debe esperar hasta que no haya otro hilo de ejecución en un bloque sincronizado en ese mismo objeto.
Object a = new Object();
Object b = new Object();
...
synchronized(a){
doStuff();
}
...
synchronized(b){
doSomeStuff();
}
...
synchronized(a){
doOtherStuff();
}
En el ejemplo anterior, un hilo conductor doOtherStuff() bloquearía otro hilo de entrar en el bloque de código proteger doStuff(). Sin embargo, un hilo podría ingresar al bloque alrededor de doSomeStuff() sin problemas ya que está sincronizado en el Objeto b, no en el Objeto a.
Cuando utiliza el modificador sincronizado en un método de instancia (un método no estático), es muy similar a tener un bloque sincronizado con "this" como argumento. Así, en el siguiente ejemplo, MethodA() y methodB() actuarán de la misma manera:
public synchronized void methodA() {
doStuff();
}
...
public void methodB() {
synchronized(this) {
doStuff();
}
}
Tenga en cuenta que si usted tiene un methodC() de la clase que no está sincronizado y no tiene un bloque sincronizado, nada impedirá que un hilo ingrese a ese método y la programación descuidada podría permitir que ese hilo acceda al código no seguro del objeto.
Si usted tiene un método estático con el modificador sincronizada, es prácticamente el mismo que tiene un bloque sincronizado con ClassName.class
como argumento (si tiene un objeto de esa clase, ClassName cn = new ClassName();
, puede acceder a ese objeto con Class c = cn.getClass();
)
class ClassName {
public void static synchronized staticMethodA() {
doStaticStuff();
}
public static void staticMethodB() {
synchronized(ClassName.class) {
doStaticStuff();
}
}
public void nonStaticMethodC() {
synchronized(this.getClass()) {
doStuff();
}
}
public static void unSafeStaticMethodD() {
doStaticStuff();
}
}
Así en el ejemplo anterior, staticMethodA() y staticMethodB() actúan de la misma manera. Un hilo de ejecución también se bloqueará para acceder al bloque de código en nonStaticMethodC() ya que se está sincronizando en el mismo objeto.
Sin embargo, es importante saber que nada impedirá que un subproceso ejecutante acceda a unSafeStaticMethodD(). Incluso si decimos que un método estático "se sincroniza en el objeto Class", no significa que sincroniza todos los accesos a los métodos en esa clase. Simplemente significa que usa el objeto Class para sincronizar. El acceso no seguro todavía es posible.
En resumen, si se sincroniza en un método estático se sincronizará en la clase (objeto) y no en una instancia (objeto). Eso significa que mientras se ejecuta un método estático, toda la clase está bloqueada. Entonces, otros métodos estáticos sincronizados también están bloqueados.
La sincronización en Java es básicamente una implementación de monitors. Al sincronizar un método no estático, el monitor pertenece a la instancia. Al sincronizar en un método estático, el monitor pertenece a la clase. La sincronización de un bloque de código es la misma idea, pero el monitor pertenece al objeto especificado. Si puede salirse con la suya, los bloques sincronizados son preferibles porque minimizan el tiempo que cada hilo pasa en el critical section
Simplemente para mejorarlo ligeramente: para los métodos estáticos, el monitor pertenece a la instancia 'Class', no a la '* class *'. Por cierto, esto es muy importante si tienes que usar más cargadores de una clase y más cargadores de una clase cargan la misma clase, entonces tenemos más de una instancia de 'Clase' para la misma clase ... –
@Andreas_D Gracias por la aclaración. No estaba al tanto de ese matiz con los cargadores de múltiples clases. – jpm
No hay prácticamente ninguna diferencia entre sincronizar un bloque y sincronizar un método.Básicamente:
void synchronized m() {...}
es lo mismo que
void m() { synchronized(this) {...} }
Por comparación, un método sincronizado estático es lo mismo que:
static void m() { synchronized(MyClass.class) {...} }
Amigo, sólo un toque. No se relaciona con su pregunta:
Si Cualquiera métodos * Cosas() no sea
this.a= /*yet another*/ new Object();
o
this.b= /*yet another*/ new Object();
entonces estás jodido. Porque el bloqueo está dentro del valor, no dentro de la referencia. Ver Java synchronized references
Java Thread adquiere un bloqueo a nivel de objeto, cuando entre en un método java ejemplo sincronizado y adquiere un bloqueo nivel clase cuando éste entre en método java síncrona estática. Al usar bloque sincronizado, solo puede bloquear la sección crítica del código y evitar el bloqueo de todo el método, lo que puede degradar el rendimiento.
- 1. Anular un método estático
- 2. Cómo sincronizar el método estático en java
- 3. @synchronized en un método estático
- 4. Bloquear() en un método estático
- 5. ¿Cómo puedo llamar a un método no estático desde un método estático en C#?
- 6. Diferencia de nivel bajo: clase no estática con método estático vs. clase estática con método estático
- 7. ¿El método estático en PHP tiene alguna diferencia con el método no estático?
- 8. Llamar a un método miembro no estático desde otro método
- 9. sincronizar el acceso a un campo estático
- 10. ¿Hay un método estático Java "nulo o igual" estático?
- 11. ¿Por qué un delegado no puede hacer referencia a un método no estático cuando se usa en un método estático?
- 12. Método "Resumen estático": ¿cómo?
- 13. GetType método estático en
- 14. Anulación de un método estático en Python
- 15. Acceso al método estático al constructor no estático?
- 16. Obtener acceso desde un método estático
- 17. ¿Qué hace sincronizado en un método estático?
- 18. método de fábrica estático público
- 19. jmock burlarse de un método estático
- 20. ¿Podemos tener un método estático virtual? (C++)
- 21. ¿El método estático es más rápido que el no estático?
- 22. ¿Cuándo debería ser un método estático?
- 23. Cómo escribir un método getitem python estático?
- 24. ¿Qué es un "método estático" en C#?
- 25. acceso simultáneo a un método estático utilidad
- 26. Llamar a un método estático en C#
- 27. Variable global en un método estático
- 28. Usando método estático vs. método de objeto
- 29. Diferencia entre el método estático y la función no estática en la memoria
- 30. compilador de C#: no se puede acceder método estático en un contexto no estático
excelente respuesta y excelente trabajo para explicarlo con ejemplos claros – emilebaizel