java - studio - ¿Es seguro llamar a un método sincronizado desde otro método sincronizado?
synchronized java ejemplo (3)
Es un método marcado con llamada sincronizada otro hilo de método sincronizado seguro.
En general, no es posible decirlo. Depende de lo que hagan los métodos y de otros métodos en la misma clase y en otras clases.
Sin embargo, podemos estar seguros de que las llamadas a method1 y method2 en el mismo objeto hechas por diferentes hilos no se ejecutarán simultáneamente. Dependiendo de lo que hagan los métodos, esto puede ser suficiente para decir que la clase es segura para subprocesos con respecto a estos métodos.
Si un método sincronizado llama a otro método sincronizado, ¿es seguro para la ejecución de subprocesos?
void synchronized method1() {
method2()
}
void synchronized method2() {
}
Desde el sitio de tutoriales de Java http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
No es posible intercalar dos invocaciones de métodos sincronizados en el mismo objeto. Cuando un hilo está ejecutando un método sincronizado para un objeto, todos los otros hilos que invocan métodos sincronizados para el mismo bloque de objetos (suspenden la ejecución) hasta que el primer hilo termina con el objeto.
cuando sale un método sincronizado, establece automáticamente una relación de pasar antes con cualquier invocación posterior de un método sincronizado para el mismo objeto. Esto garantiza que los cambios en el estado del objeto sean visibles para todos los hilos
Por lo tanto, Java se asegurará de que si 2 subprocesos están ejecutando el mismo método, los métodos no se ejecutarán de manera consensual sino uno tras otro.
Pero debe conocer el problema Liveness, http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html
Y también si está bloqueando innecesariamente, porque en el código que utilizó, que bloquea todo el objeto, si su objeto solo necesita acceso de sincronización a una variable, simplemente debe bloquear esa variable.
Sí, cuando marcas los métodos como synchronized
, entonces realmente estás haciendo esto:
void method1() {
synchronized (this) {
method2()
}
}
void method2() {
synchronized (this) {
}
}
Cuando la llamada del hilo entra en method2 desde method1, entonces se asegurará de que mantiene el bloqueo en this
, que ya lo hará, y luego puede pasar.
Cuando el hilo se introduce directamente en method1 o method2, bloqueará hasta que pueda obtener el bloqueo ( this
), y luego ingresará.
Como señaló James Black en los comentarios, debe tener en cuenta lo que hace dentro del cuerpo del método.
private final List<T> data = new ArrayList<T>();
public synchronized void method1() {
for (T item : data) {
// ..
}
}
public void method3() {
data.clear();
}
De repente, no es seguro para subprocesos porque está viendo una ConcurrentModificationException
en su futuro porque el method3
no está sincronizado y, por lo tanto, podría ser llamado por el subproceso A, mientras que el subproceso B está funcionando en el method1
.