practice - Buscando un sorprendente programa concurrente de Java.
thread object java (7)
¿Qué tal esto?
class ObjectReference {
private volatile Object obj = null;
public void set(Object obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
this.obj = obj;
synchronized (this) {
notifyAll();
}
}
/**
* This method never returns null
*/
public Object waitAndGet() {
if (obj != null) {
return obj;
}
synchronized (this) {
wait();
return obj;
}
}
}
Usted podría obtener null
de waitAndGet()
realidad. Ver - ¿Ocurren realmente despertares espurios?
Dado que estoy escribiendo un generador de perfiles que se centra en los aspectos de la concurrencia , estoy buscando un buen ejemplo artificial que use mecanismos de sincronización en Java . Mi perfilador hace visibles algunas acciones relacionadas con el enhebrado; por ejemplo:
- llamando a notificar / esperar
- hilo cambia su estado
- un hilo se compite con otro hilo para un bloqueo de monitor
- un subproceso ha adquirido un bloqueo de monitor después de luchar por él con otro
- Medir el tiempo de ejecución de cada método.
- qué hilo ha accedido a un determinado método y con qué frecuencia
- etc.
Entonces, lo que estoy buscando es un programa Java que parece entenderse a primera vista , pero cuando lo ejecutas, empiezas a preguntarte sobre los resultados. Espero que mi perfilador pueda detectar lo que sucede en segundo plano.
Para aclararme, les doy un ejemplo, el libro Java Concurrency in Practice de Brian Goetz da ejemplos de código "tóxicos" que se utilizan para aprender.
@NotThreadSafe
public class ListHelper<E> {
public List<E> list =
Collections.synchronizedList(new ArrayList<E>());
...
public synchronized boolean putIfAbsent(E x) {
boolean absent = !list.contains(x);
if (absent)
list.add(x);
return absent;
}
}
Se pretende que sea una extensión de una clase segura para subprocesos, mediante el método putIfAbsent
. Dado que la list
está sincronizada, pero putIfAbsent
utiliza otro bloqueo para proteger el estado como los métodos definidos en la lista.
El generador de perfiles podría mostrar los bloqueos de monitor usados y, para sorpresa del usuario (o no ...) el usuario vería que hay dos bloqueos de monitor posibles en lugar de uno.
No me gusta mucho este ejemplo, pero no preguntaría si ya tuviera un montón de buenos ejemplos.
Descubrí que mi pregunta es similar a esta: ¿Cuál es el problema de concurrencia más frecuente que ha encontrado en Java? y patrones de error de concurrencia de Java .
Pero se refieren solo a programas concurrentes rotos. También estoy buscando implementaciones seguras para subprocesos, pero aún no es obvio que sean seguras para subprocesos.
Consulte el boletín de especialistas de Java para ver un flujo constante de pequeños rompecabezas de Java, muchos de los cuales deben ajustarse a sus necesidades de prueba.
Eche un vistazo a la lista de descripciones de errores de FindBugs , específicamente aquellas que pertenecen a la categoría de corrección de multiproceso (columna de la tabla derecha).
Cada uno de estos errores contiene referencias sobre por qué un idioma particular es malo y cómo puede resolverse.
Recomendaría buscar (o preguntar a los autores) el conjunto de pruebas de rendimiento de IBM ConTest, ya que contiene una serie de errores de concurrencia de Java (desafortunadamente no son grandes programas de código abierto). Lo bueno de este punto de referencia es que los errores ya están documentados (tipo y ubicación).
Si desea encontrar más programas, recomendaría echar un vistazo a algunos de los trabajos de investigación en el área de pruebas de software / calidad de los programas concurrentes. Deben indicar los programas de muestra que han utilizado en sus estudios.
Si todo lo demás falla, puede intentar buscar en GitHub (o servicio similar) depósitos que contengan los mecanismos de concurrencia necesarios (es decir, sincronización). Es posible que encuentre una gran cantidad de código Java de esa manera, el único problema es que los errores no están documentados (a menos que busque correcciones de confirmación).
Creo que estas tres sugerencias le proporcionarán suficientes programas para probar su generador de perfiles de concurrencia.
Volvería en el tiempo, tal vez como siete años o más, y encontraría un código de código abierto de la era anterior a java.util.concurrent. Casi cualquier cosa que haga rodar su propia concurrencia tendrá algunos errores sutiles, porque la concurrencia es difícil de hacer bien.
El problema de los filósofos es un ejemplo clásico de concurrencia. Este enlace tiene una solución posible y se puede encontrar más en la web.
Como se describe en el primer enlace, este ejemplo ilustra muchos de los problemas comunes de concurrencia. ¡Por favor, deja que tu perfilador muestre cuántos puede rastrear!