这个线程安全吗?

时间:2014-05-16 13:05:46

标签: java multithreading thread-safety

这个线程安全吗?我需要锁吗?

public class Load {

    //private final Object lock = new Object();

    private final Map<String, String> confs = new HashMap<String, String>();

   public void addValue(String key, String value) {
       //synchronized (lock)
       confs.put(key, value);

   }

   public String getValue(String key) {
      //synchronized (lock)
      return confs.get(key);
   }
}

我认为没有锁定它的线程是安全的。 当我做新的Load()时,会有新的hashmap实例。这是对的吗?

4 个答案:

答案 0 :(得分:1)

默认情况下,

HashMap不是线程安全的。如果您需要线程安全版本,请使用ConcurrentHashMap,或者您可以手动使用锁。

答案 1 :(得分:0)

这是线程安全。如果两个线程同时调用addValue,则HasMap很可能会损坏。

您可以使用ConcurrentHasMap修复此问题。

见:

Hashmap concurrency issue

特别是

A Beautiful Race Condition

这里有一个使用Load课程的演示,可能会崩溃。

public class Load {

    private final Map<String, String> confs = new HashMap<String, String>();

    public void addValue(String key, String value) {
        confs.put(key, value);

    }

    public String getValue(String key) {
        //synchronized (lock)
        return confs.get(key);
    }
}

public class Loader implements Runnable {
    private final Load load;

    public Loader (Load load) {
        this.load = load;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100000; i++) {
            load.addValue("" + i, "Value:" + i);
        }
    }

}
public void test() throws InterruptedException {
    System.out.println("Hello");
    Load load = new Load();
    Loader l1 = new Loader(load);
    Loader l2 = new Loader(load);
    Thread t1 = new Thread(l1);
    Thread t2 = new Thread(l2);
    t1.start();
    t2.start();
    t1.join();
    t2.join();
}

答案 2 :(得分:0)

不,它不是线程安全的。尝试使用ConcurrentHashMap

public class Load {

    //private final Object lock = new Object();

    private final Map<String, String> confs = new ConcurrentHashMap<String, String>();

   public void addValue(String key, String value) {
       //synchronized (lock)
       confs.put(key, value);

   }

   public String getValue(String key) {
      //synchronized (lock)
      return confs.get(key);
   }
}

答案 3 :(得分:0)

不,它不是线程安全的。你需要锁定代码。尝试使用ConcurrentHasMap。

如果您使用了普通的HashMap,请检查此code,这会给您一个例外:

package com.concretepage;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ConcurrentHashMapTest implements Runnable{
  private String name;
  private static Map<String,String> conpage=new ConcurrentHashMap<String,String>();
  ConcurrentHashMapTest(String name){
      conpage.put("1","A");
      conpage.put("2","B");
      conpage.put("3","C");
      this.name=name;
  }
  public void run() {
    try{
      Iterator<String> it = conpage.keySet().iterator();
      while(it.hasNext()){
        String key=it.next();
        conpage.put("A"+key, "A"+key);
      }
      System.out.println(name +" completed.");
    }catch(Exception e){
          e.printStackTrace();
    }finally{
    }
  }
  public static void main(String[] args) {
      ExecutorService  executor= Executors.newCachedThreadPool();
      executor.execute(new ConcurrentHashMapTest("Thread one"));
      executor.execute(new ConcurrentHashMapTest("Thrad two"));
      executor.shutdownNow();
  }
}