-
CSR
-
Resolution: Approved
-
P4
-
None
-
behavioral
-
minimal
-
-
Java API
-
SE
Summary
Synchronization has been narrowed in the publish()
methods of java.util.logging.Handler
sub-classes to avoid deadlock risk.
Problem
By synchronizing around code which calls back to arbitrary user code when formatting LogRecord
instances, Handler
implementations will create conditions in which deadlocks can occur.
Solution
By narrowing the regions of code being explicitly synchronized, deadlock risk can be removed.
This necessarily requires removal of the synchronized
keywords on any implementations of the publish()
in StreamHandler
and its subclasses, but may also require changes within publish()
method implementations to narrow any synchronized regions. As StreamHandler
is publicly subclassable, this change to its publish()
method must be specified and new restrictions placed on overrides of this method.
Specification
Documentation change to java.util.logging.Handler
class-level JavaDoc:
+ <p>
+ * <h2><a id=threadSafety>Thread Safety and Deadlock Risk in Handlers</a></h2>
+ *
+ * Implementations of {@code Handler} should be thread-safe. Handlers are
+ * expected to be invoked concurrently from arbitrary threads. However,
+ * over-use of synchronization may result in unwanted thread contention,
+ * performance issues or even deadlocking.
+ * <p>
+ * In particular, subclasses should avoid acquiring locks around code which
+ * calls back to arbitrary user-supplied objects, especially during log record
+ * formatting. Holding a lock around any such callbacks creates a deadlock risk
+ * between logging code and user code.
+ * <p>
+ * As such, general purpose {@code Handler} subclasses should not synchronize
+ * their {@link #publish(LogRecord)} methods, or call {@code super.publish()}
+ * while holding locks, since these are typically expected to need to process
+ * and format user-supplied arguments.
*
* @since 1.4
*/
Api note for Handler publish method:
+ * <p>
+ * @apiNote To avoid the risk of deadlock, implementations of this method
+ * should avoid holding any locks while calling out to application code,
+ * such as the formatting of {@code LogRecord}.
*
* @param record description of the log event. A null record is
* silently ignored and is not published
*/
public abstract void publish(LogRecord record);
Specification change/clarification for the publish(LogRecord)
methods in java.util.logging.StreamHandler
, java.util.logging.ConsoleHandler
and java.util.logging.SocketHandler
:
+ * @implSpec This method is not synchronized, and subclasses must not define
+ * overridden {@code publish()} methods to be {@code synchronized} if they
+ * call {@code super.publish()} or format user arguments. See the
+ * {@linkplain Handler##threadSafety discussion in java.util.logging.Handler}
+ * for more information.
- csr of
-
JDK-8353683 [REDO] j.u.l.Handler classes create deadlock risk via synchronized publish() method
-
- Resolved
-
-
JDK-8349206 j.u.l.Handler classes create deadlock risk via synchronized publish() method
-
- Closed
-