¿Cuáles son las formas posibles de hacer código seguro para subprocesos sin utilizar la palabra clave synchronized
?Código seguro para subprocesos sin utilizar la palabra clave `synchronized`?
Respuesta
sólo tienen las variables/referencias locales a los métodos. O asegúrate de que las variables de instancia sean inmutables.
¿No serían aceptables las variables de instancia inmutables? – duffymo
@duffymo edited – NimChimpsky
nice - corto y al grano. –
Puede hacer que su código sea seguro para subprocesos haciendo que todos los datos sean inmutables, si no hay mutabilidad, todo es seguro para subprocesos.
En segundo lugar, es posible que desee echar un vistazo a API simultánea de Java que tiene la disposición para proporcionar bloqueos de lectura/escritura que funcionan mejor en caso de que haya muchos lectores y algunos escritores. La palabra clave pura sincronizada también bloqueará a dos lectores.
En realidad, muchas maneras:
- Sin necesidad de sincronización en absoluto si usted no tiene estado mutable.
- No hay necesidad de sincronización si el estado mutable está limitado a un único hilo. Esto se puede hacer utilizando variables locales o
java.lang.ThreadLocal
. - También puede usar sincronizadores incorporados.
java.util.concurrent.locks.ReentrantLock
tiene la misma funcionalidad que el bloqueo al que accede cuando usa los bloques y métodossynchronized
, y es aún más poderoso.
Prefiero (2), pero no estoy seguro de si es posible implementar mensajes sin utilizar la palabra clave 'sincronizada'. ¿Puedo hacer una cola productor-consumidor sin 'sincronizar'? –
No importa - Puedo, usando java.util.concurrent.Semaphore. –
@MartinJames Cualquiera de las clases simultáneas como colas e intercambiadores se puede utilizar sin sincronización. (Usan Lock en su lugar) The Disrupter admite mensajería sin bloqueos o sincronización. (Tengo una biblioteca que hace esto también) –
¿Por qué lo necesitas?
Usando sólo la variable local/referencias no van a resolver la mayor parte de las necesidades de negocio complejos. Además, si la variable de instancia es inmutable, sus referencias aún se pueden cambiar por otros hilos.
Una opción es utilizar algo así como un SingleThreadModel, pero está muy desaconsejado y desaconsejado.
u también puede mirar a api concurrente como se sugirió anteriormente por Kal
"si la variable de instancia es inmutable, sus referencias aún se pueden cambiar" no, no pueden – NimChimpsky
¿puede explicar eso? Como lo veo es que si tengo una variable de instancias String s = "xyz", My thread1 puede cambiar la referencia a s = "abc"; y thread2 ahora obtendrá s = "abc" – Kshitij
s es una referencia, ha cambiado, no es inmutable, necesitaría "s final string" – NimChimpsky
Para mantener la previsibilidad debe garantizar ya sea todo el acceso a los datos mutables se realiza de forma secuencial o manejar los problemas causados por el acceso paralelo.
La protección más gruesa usa la palabra clave synchronized
. Más allá de eso, hay al menos dos niveles de posibilidad, cada uno con sus beneficios.
Cerraduras/Semáforos
Estos pueden ser muy eficaces. Por ejemplo, si tiene una estructura que muchos subprocesos leen, pero que solo se actualiza en uno, es posible que encuentre útil un ReadWriteLock
.
cerraduras pueden ser mucho más eficiente si se elige la cerradura para que coincida con el algoritmo.
Atomics
El uso de AtomicReference
por ejemplo, puede proporcionar a menudo bloquear por completo la funcionalidad gratuita. Esto generalmente puede proporcionar grandes beneficios.
El razonamiento detrás de atomics es permitirles fallar, pero decirles que fallaron de una manera que usted puede manejarlo.
Por ejemplo, si desea cambiar un valor, puede leerlo y luego escribir su nuevo valor siempre que siga siendo el valor anterior. Esto se llama "comparar y establecer" o cas
y generalmente se puede implementar en hardware, por lo que es extremadamente eficiente. Todo lo que necesita es algo así como:
long old = atomic.get();
while (!atomic.cas(old, old+1)) {
// The value changed between my get and the cas. Get it again.
old = atomic.get();
}
Tenga en cuenta, sin embargo, que la previsibilidad no siempre es un requisito.
- 1. ¿Por qué este código funciona sin la palabra clave insegura?
- 2. Java: cuándo utilizar la palabra clave 'this'
- 3. ¿HttpContext.Current.Cache es seguro para subprocesos?
- 4. ¿Este código es seguro para subprocesos? ¿Cómo puedo hacer que sea seguro para subprocesos?
- 5. ¿Por qué este código no es seguro para subprocesos?
- 6. Uso de TDD para expulsar el código seguro para subprocesos
- 7. anidada sincronizada palabra clave
- 8. ¿SecureRandom es seguro para subprocesos?
- 9. Fábrica de objetos singleton: ¿este código es seguro para subprocesos?
- 10. Enum.TryParse - ¿es seguro para subprocesos?
- 11. ¿Stream.Write es seguro para subprocesos?
- 12. C++ Segmento seguro para subprocesos
- 13. ¿PrintWriter es seguro para subprocesos?
- 14. EventAggregator, ¿es seguro para subprocesos?
- 15. ¿SQLite.Net es seguro para subprocesos?
- 16. ¿Es PHP seguro para subprocesos?
- 17. NSTimer ¿es seguro para subprocesos?
- 18. ¿Es itertools seguro para subprocesos?
- 19. C# Singleton seguro para subprocesos
- 20. Asegúrese de que mi código es seguro para subprocesos
- 21. ¿MongoDB es seguro para subprocesos?
- 22. ¿DWScript es seguro para subprocesos?
- 23. ¿Es System.ServiceModel.Channels.BufferManager seguro para subprocesos?
- 24. Declaración de variables sin palabra clave var
- 25. C++ palabra clave explícita para la función sin argumentos
- 26. ¿Cómo utilizar la palabra clave BETWEEN en Entity Framework?
- 27. ¿La palabra clave "var" dificulta la legibilidad del código?
- 28. 5 formas de utilizar la palabra clave estática en Java
- 29. ¿Cuándo NO utilizar la palabra clave estática en Java?
- 30. ¿Es seguro usar la palabra python "tipo" en mi código?
¿por qué cerrar? Es una buena pregunta sucinta – NimChimpsky
@NimChimpsky Yo tampoco lo sé, la pregunta me parece perfectamente válida. Definitivamente es responsable y las respuestas no son algo subjetivo. – Malcolm