src/share/classes/java/util/logging/Handler.java
Print this page
@@ -46,15 +46,23 @@
*/
public abstract class Handler {
private static final int offValue = Level.OFF.intValue();
private LogManager manager = LogManager.getLogManager();
- private Filter filter;
- private Formatter formatter;
- private Level logLevel = Level.ALL;
- private ErrorManager errorManager = new ErrorManager();
- private String encoding;
+
+ // We're using volatile here to avoid synchronizing getters, which
+ // would prevent other threads from calling isLoggable()
+ // while publish() is executing.
+ // On the other hand, setters will be synchronized to exclude concurrent
+ // execution with more complex methods, such as StreamHandler.publish().
+ // We wouldn't want 'level' to be changed by another thread in the middle
+ // of the execution of a 'publish' call.
+ private volatile Filter filter;
+ private volatile Formatter formatter;
+ private volatile Level logLevel = Level.ALL;
+ private volatile ErrorManager errorManager = new ErrorManager();
+ private volatile String encoding;
// Package private support for security checking. When sealed
// is true, we access check updates to the class.
boolean sealed = true;
@@ -108,11 +116,11 @@
* <p>
* @param newFormatter the <tt>Formatter</tt> to use (may not be null)
* @exception SecurityException if a security manager exists and if
* the caller does not have <tt>LoggingPermission("control")</tt>.
*/
- public void setFormatter(Formatter newFormatter) throws SecurityException {
+ public synchronized void setFormatter(Formatter newFormatter) throws SecurityException {
checkPermission();
// Check for a null pointer:
newFormatter.getClass();
formatter = newFormatter;
}
@@ -136,11 +144,11 @@
* @exception SecurityException if a security manager exists and if
* the caller does not have <tt>LoggingPermission("control")</tt>.
* @exception UnsupportedEncodingException if the named encoding is
* not supported.
*/
- public void setEncoding(String encoding)
+ public synchronized void setEncoding(String encoding)
throws SecurityException, java.io.UnsupportedEncodingException {
checkPermission();
if (encoding != null) {
try {
if(!java.nio.charset.Charset.isSupported(encoding)) {
@@ -172,11 +180,11 @@
*
* @param newFilter a <tt>Filter</tt> object (may be null)
* @exception SecurityException if a security manager exists and if
* the caller does not have <tt>LoggingPermission("control")</tt>.
*/
- public void setFilter(Filter newFilter) throws SecurityException {
+ public synchronized void setFilter(Filter newFilter) throws SecurityException {
checkPermission();
filter = newFilter;
}
/**
@@ -196,11 +204,11 @@
*
* @param em the new ErrorManager
* @exception SecurityException if a security manager exists and if
* the caller does not have <tt>LoggingPermission("control")</tt>.
*/
- public void setErrorManager(ErrorManager em) {
+ public synchronized void setErrorManager(ErrorManager em) {
checkPermission();
if (em == null) {
throw new NullPointerException();
}
errorManager = em;
@@ -227,12 +235,13 @@
* @param msg a descriptive string (may be null)
* @param ex an exception (may be null)
* @param code an error code defined in ErrorManager
*/
protected void reportError(String msg, Exception ex, int code) {
+ final ErrorManager em = errorManager;
try {
- errorManager.error(msg, ex, code);
+ em.error(msg, ex, code);
} catch (Exception ex2) {
System.err.println("Handler.reportError caught:");
ex2.printStackTrace();
}
}
@@ -262,11 +271,11 @@
* Get the log level specifying which messages will be
* logged by this <tt>Handler</tt>. Message levels lower
* than this level will be discarded.
* @return the level of messages being logged.
*/
- public synchronized Level getLevel() {
+ public Level getLevel() {
return logLevel;
}
/**
* Check if this <tt>Handler</tt> would actually log a given <tt>LogRecord</tt>.
@@ -280,15 +289,15 @@
* @param record a <tt>LogRecord</tt>
* @return true if the <tt>LogRecord</tt> would be logged.
*
*/
public boolean isLoggable(LogRecord record) {
- int levelValue = getLevel().intValue();
+ final int levelValue = getLevel().intValue();
if (record.getLevel().intValue() < levelValue || levelValue == offValue) {
return false;
}
- Filter filter = getFilter();
+ final Filter filter = getFilter();
if (filter == null) {
return true;
}
return filter.isLoggable(record);
}