Me preguntaba si tiene un método estático que no esté sincronizado, pero que no modifique ninguna variable estática, ¿es seguro para subprocesos? ¿Qué pasa si el método crea variables locales dentro de él? Por ejemplo, ¿el siguiente código es seguro para subprocesos?
public static String[] makeStringArray( String a, String b ){
return new String[]{ a, b };
}
Entonces, si tengo dos hilos que llaman a este método de forma continua y simultánea, uno con perros (diga "gran danés" y "perro toro") y el otro con gatos (diga "persa" y "siamés") alguna vez tendré gatos y perros en la misma matriz? ¿O los gatos y los perros nunca estarán dentro de la misma invocación del método al mismo tiempo?
Respuestas:
Este método es 100% seguro para subprocesos, lo sería incluso si no lo fuera
static
. El problema con la seguridad de subprocesos surge cuando necesita compartir datos entre subprocesos: debe cuidar la atomicidad, la visibilidad, etc.Este método solo funciona con parámetros, que residen en la pila y referencias a objetos inmutables en el montón. Stack es inherentemente local al hilo , por lo que nunca se comparte información.
Los objetos inmutables (
String
en este caso) también son seguros para subprocesos porque una vez creados no se pueden cambiar y todos los subprocesos ven el mismo valor. Por otro lado, si el método aceptara (mutable)Date
, podría haber tenido un problema. Dos hilos pueden modificar simultáneamente esa misma instancia de objeto, causando condiciones de carrera y problemas de visibilidad.fuente
Un método solo puede ser inseguro para subprocesos cuando cambia algún estado compartido. Si es estático o no es irrelevante.
fuente
La función es perfectamente segura para hilos.
Si lo piensas ... asume lo que sucedería si esto fuera diferente. Todas las funciones habituales tendrían problemas de subprocesos si no estuvieran sincronizadas, por lo que todas las funciones de API en el JDK tendrían que estar sincronizadas, ya que potencialmente podrían ser llamadas por múltiples subprocesos. Y dado que la mayor parte del tiempo la aplicación usa alguna API, las aplicaciones multiproceso serían efectivamente imposibles.
Esto es demasiado ridículo para pensarlo, así que solo para usted: los métodos no son seguros si hay una razón clara por la que podría haber problemas. Intente siempre pensar en qué pasaría si hubiera varios subprocesos en mi función, y qué pasaría si tuviera un depurador de pasos y avanzara un paso tras otro el primero ... luego el segundo hilo ... tal vez el segundo nuevamente ... habría problemas? Si encuentra uno, no es seguro para subprocesos.
Tenga en cuenta también que la mayoría de las clases de Java 1.5 Collection no son seguras para subprocesos, excepto aquellas donde se indica, como ConcurrentHashMap.
Y si realmente quieres sumergirte en esto, mira de cerca la palabra clave volátil y TODOS sus efectos secundarios. Eche un vistazo a las clases Semaphore () y Lock (), y sus amigos en java.util.Concurrent. Lea todos los documentos de API alrededor de las clases. Vale la pena aprender y satisfacer también.
Perdón por esta respuesta demasiado elaborada.
fuente
Use la
static
palabra clave con métodos estáticos sincronizados para modificar datos estáticos compartidos entre subprocesos. Con lastatic
palabra clave, todos los hilos creados competirán por una única versión del método.El uso de la
volatile
palabra clave junto con los métodos de instancia sincronizada garantizará que cada subproceso tenga su propia copia de los datos compartidos y que no se filtre lectura / escritura entre los subprocesos.fuente
Los objetos de cadena que son inmutables es otra razón para el escenario anterior seguro para subprocesos. En cambio, si se utilizan objetos mutables (por ejemplo, makeMutableArray ...), entonces seguramente se romperá la seguridad de subprocesos.
fuente