classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

java.util.Properties -- make it thread-safe?


From: Sascha Brawer
Subject: java.util.Properties -- make it thread-safe?
Date: Fri, 15 Feb 2002 12:53:24 +0100

Hello,

this proposed patch would make the following methods of
java.util.Properties thread-safe. Comments?

- load
- save
- store
- propertyNames
- list(java.io.PrintWriter)
- list(java.io.PrintStream)

Classpath's implementation of other methods, like getProperty and
setProperty, are already thread-safe because Properties is a subclass of
java.util.Hashtable.

Sun's current JavaDoc (J2SE 1.4) does not mention whether
java.util.Properties is supposed to be usable from multiple threads
without additional synchronization.  However, one might be able to infer
it from the fact that it is a subclass of java.util.Hashtable.

Sun's JavaDoc (JDK1.1) specified only load and save as synchronized.
(Newer javadoc versions do not emit "synchronized" anymore).

Actually, I am curious what people do in general for determining what the
Sun reference implementation does about synchronization. 
Nondeterministic behavior is not easy to observe, after all.  And I think
running javap to see which methods are synchronized is out of the
question, since this would count as decompilation.

Or should one file bug reports with Sun, saying that the spec is not clear?

-- Sascha



cvs diff -u java/util/Properties.java
Index: java/util/Properties.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/util/Properties.java,v
retrieving revision 1.13
diff -u -r1.13 Properties.java
--- java/util/Properties.java   22 Jan 2002 22:27:01 -0000      1.13
+++ java/util/Properties.java   15 Feb 2002 11:07:14 -0000
@@ -135,10 +135,16 @@
    * label   = Name:\<code></code>u0020
    * </pre>
    *
+   * <p>It is safe to call this method while other threads are trying
+   * to modify this Properties object; no external synchronization
+   * needs to be performed.
+   *
    * @param in the input stream
    * @exception IOException if an error occurred when reading
-   * from the input.  */
-  public void load(InputStream inStream) throws IOException
+   *            from the input.
+   */
+  public synchronized void load(InputStream inStream)
+    throws IOException
   {
     // The spec says that the file must be encoded using ISO-8859-1.
     BufferedReader reader =
@@ -278,11 +284,16 @@
   /**
    * Calls <code>store(OutputStream out, String header)</code> and
    * ignores the IOException that may be thrown.
+   *
+   * <p>It is safe to call this method while other threads are trying
+   * to modify this Properties object; no external synchronization
+   * needs to be performed.
+   *
    * @deprecated use store instead.
    * @exception ClassCastException if this property contains any key or
    * value that isn't a string.
    */
-  public void save(OutputStream out, String header)
+  public synchronized void save(OutputStream out, String header)
   {
     try
       {
@@ -310,12 +321,17 @@
    * that are not in the ascii range 33 to 127 are written in the
    * <code>\</code><code>u</code>xxxx Form.
    *
+   * <p>It is safe to call this method while other threads are trying
+   * to modify this Properties object; no external synchronization
+   * needs to be performed.
+   *
    * @param out the output stream
    * @param header the header written in the first line, may be null.
    * @exception ClassCastException if this property contains any key or
    * value that isn't a string.
    */
-  public void store(OutputStream out, String header) throws IOException
+  public synchronized void store(OutputStream out, String header)
+    throws IOException
   {
     // The spec says that the file must be encoded using ISO-8859-1.
     PrintWriter writer
@@ -381,7 +397,7 @@
     return defaultValue;
   }
 
-  private final void addHashEntries(Hashtable base)
+  private final synchronized void addHashEntries(Hashtable base)
   {
     if (defaults != null)
       defaults.addHashEntries(base);
@@ -393,6 +409,10 @@
   /**
    * Returns an enumeration of all keys in this property list, including
    * the keys in the default property list.
+   *
+   * <p>It is safe to call this method while other threads are trying
+   * to modify this Properties object; no external synchronization
+   * needs to be performed.
    */
   public Enumeration propertyNames()
   {
@@ -403,7 +423,10 @@
     // particularly better way to ensure that duplicates are
     // ignored.
     Hashtable t = new Hashtable();
+
+    /* addHashEntries is synchronized. */
     addHashEntries(t);
+
     return t.keys();
   }
 
@@ -512,12 +535,17 @@
   /**
    * Writes the key/value pairs to the given print stream.  They are
    * written in the way, described in the method store.
+   *
+   * <p>It is safe to call this method while other threads are trying
+   * to modify this Properties object; no external synchronization
+   * needs to be performed.
+   *
    * @param out the stream, where the key/value pairs are written to.
    * @exception ClassCastException if this property contains any key or
    * value that isn't a string.
    * @see #store
    */
-  public void list(PrintStream out)
+  public synchronized void list(PrintStream out)
   {
     Enumeration keys = keys();
     Enumeration elts = elements();
@@ -540,7 +568,7 @@
    * @see #list(java.io.PrintStream)
    * @since JDK1.1
    */
-  public void list(PrintWriter out)
+  public synchronized void list(PrintWriter out)
   {
     Enumeration keys = keys();
     Enumeration elts = elements();





reply via email to

[Prev in Thread] Current Thread [Next in Thread]