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);
     }