title: Singleton and multithread
body: <p>Please, look at the classes below and tell me if the code below is thread safe. The point of my question is that one class whose <code>static</code> method and that method calls singleton instance's method. Also, the <code>static</code> method is invoked by <code>Runnable</code> instance. So I am asking you guys to see the codes - <code>static</code> method and it calls singleton's method in multi thread environment - is safe?</p>
  
  <p>I will really appreciate if you answer my question.</p>
  
  <pre><code>import java.io.BufferedReader;
  import java.io.FileReader;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.StringTokenizer;
  
  public class SingletonCls {
      private static SingletonCls singletonInstance = null;
  
      private SingletonCls() {
      }
  
      public static SingletonCls getIntance() {
          if (SingletonCls.singletonInstance == null) {
              singletonInstance = new SingletonCls();
          }
          return SingletonCls.singletonInstance;
      }
  
      public List&lt;Map&lt;String, String&gt;&gt; call(String id) throws Exception {
          List&lt;Map&lt;String, String&gt;&gt; list = new ArrayList&lt;Map&lt;String, String&gt;&gt;();
          BufferedReader br = null;
          final String col = "col";
          try {
              br = new BufferedReader(new FileReader("test.txt"));
              String lineStr = null;
              while ((lineStr = br.readLine()) != null) {
                  StringTokenizer st = new StringTokenizer(lineStr, ",");
                  int colIdx = 1;
  
                  if (lineStr.startsWith(id)) {
                      Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
                      while (st.hasMoreTokens()) {
                          String value = st.nextToken();
                          map.put(col + (colIdx++), value);
                      }
                      list.add(map);
                  }
              }
  
          } finally {
              if (br != null) {
                  br.close();
              }
          }
          return list;
      }
  }
  
  
  import java.io.IOException;
  import java.util.List;
  import java.util.Map;
  
  public class TestSingleTonCaller {
  
      public static List&lt;Map&lt;String, String&gt;&gt; getData(String id) throws Exception {
          List&lt;Map&lt;String, String&gt;&gt; list = SingletonCls.getIntance().call(id);
          return list;
      }
  }
  
  
  
  import java.io.IOException;
  import java.util.List;
  import java.util.Map;
  
  public class RunnableSingleTonExe implements Runnable {
      private final String id;
  
      public RunnableSingleTonExe(String inId) {
          this.id = inId;
      }
  
      public void run() {
          try {
              List&lt;Map&lt;String, String&gt;&gt; list = TestSingleTonCaller
                      .getData(this.id);
              System.out.println("thread id:" + this.id + "  list &gt; "
                      + (list == null ? "" : list.toString()));
          } catch (IOException e) {
              Thread.currentThread().interrupt();
              e.printStackTrace();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>