En Java, puede considerar el comportamiento del programa sincronizado incorrectamente indefinido.
Java 7 JLS usa la palabra "indefinido" una vez, en 17.4.8. Ejecuciones y requisitos de causalidad :
Usamos f|d
para denotar la función dada restringiendo el dominio de f
to d
. Para todos x
en d
, f|d(x) = f(x)
y para todos los que x
no están d
, nof|d(x)
está definido ...
La documentación de la API de Java especifica algunos casos en que los resultados no están definidos, por ejemplo, en la fecha del constructor (en desuso) (int año, int mes, int día) :
El resultado no está definido si un argumento dado está fuera de los límites ...
Javadocs para el estado ExecutorService.invokeAll (Collection) :
Los resultados de este método no están definidos si la colección dada se modifica mientras esta operación está en progreso ...
Se puede encontrar un tipo menos formal de comportamiento "indefinido", por ejemplo, en ConcurrentModificationException , donde los documentos API utilizan el término "mejor esfuerzo":
Tenga en cuenta que el comportamiento a prueba de fallas no puede garantizarse ya que, en términos generales, es imposible hacer garantías duras en presencia de modificaciones concurrentes no sincronizadas. Las operaciones a prueba de fallas se basan ConcurrentModificationException
en el mejor esfuerzo . Por lo tanto, sería un error escribir un programa que dependiera de esta excepción para su corrección ...
Apéndice
Uno de los comentarios de las preguntas se refiere a un artículo de Eric Lippert que proporciona una introducción útil a los temas: comportamiento definido por la implementación .
Recomiendo este artículo para el razonamiento independiente del lenguaje, aunque vale la pena tener en cuenta que el autor se dirige a C #, no a Java.
Tradicionalmente decimos que un idioma de lenguaje de programación tiene un comportamiento indefinido si el uso de ese idioma puede tener algún efecto; puede funcionar de la manera que espera o puede borrar su disco duro o bloquear su máquina. Además, el autor del compilador no tiene la obligación de advertirle sobre el comportamiento indefinido. (¡Y de hecho, hay algunos lenguajes en los que la especificación del lenguaje permite que los programas que usan modismos de "comportamiento indefinido" bloqueen el compilador!) ...
Por el contrario, un idioma que tiene un comportamiento definido por la implementación es aquel en el que el autor del compilador tiene varias opciones sobre cómo implementar la característica y debe elegir una. Como su nombre lo indica, el comportamiento definido por la implementación está al menos definido. Por ejemplo, C # permite que una implementación arroje una excepción o produzca un valor cuando una división entera se desborda, pero la implementación debe elegir una. No puede borrar su disco duro ...
¿Cuáles son algunos de los factores que llevan a un comité de diseño del lenguaje a dejar ciertas expresiones idiomáticas como comportamientos indefinidos o definidos por la implementación?
El primer factor importante es: ¿hay dos implementaciones existentes del lenguaje en el mercado que no están de acuerdo con el comportamiento de un programa en particular? ...
El siguiente factor importante es: ¿la característica presenta naturalmente muchas posibilidades diferentes para la implementación, algunas de las cuales son claramente mejores que otras? ...
Un tercer factor es: ¿ es la característica tan compleja que sería difícil o costoso especificar un desglose detallado de su comportamiento exacto? ...
Un cuarto factor es: ¿la función impone una gran carga al compilador para analizar? ...
Un quinto factor es: ¿la característica impone una gran carga en el entorno de tiempo de ejecución? ...
Un sexto factor es: ¿definir el comportamiento impide alguna optimización importante? ...
Esos son solo algunos factores que vienen a la mente; Por supuesto, hay muchos, muchos otros factores que los comités de diseño de lenguaje debaten antes de hacer una característica "implementación definida" o "indefinida".
Lo anterior es solo una cobertura muy breve; El artículo completo contiene explicaciones y ejemplos de los puntos mencionados en este extracto; es mucho vale la pena leer. Por ejemplo, los detalles dados para el "sexto factor" pueden dar una idea de la motivación para muchas declaraciones en el Modelo de memoria Java ( JSR 133 ), lo que ayuda a comprender por qué se permiten algunas optimizaciones, lo que lleva a un comportamiento indefinido mientras que otras están prohibidas, lo que lleva a limitaciones como suceder antes y requisitos de causalidad .
Ninguno de los materiales del artículo es particularmente nuevo para mí, pero me condenaría si alguna vez lo viera presentado de una manera tan elegante, concisa y comprensible. Increíble.