当线程处于特定块时,避免全局修改静态对象

时间:2016-03-29 17:57:30

标签: java multithreading static concurrentmodification

我有两个类,First类(ClassServletA.java)是HttpServlet,它在ishdress中存储ipaddress和访问时间,我想每天在DB中备份HashMap,所以我正在调度任务和存储DB中的静态HashMap对象,然后重新初始化HashMap(存储在DB中之后)。

是否可以全局锁定静态对象?

 public class ClassServletA {
  public static  Map<String,String> myMap = new HashMap<String, String>();

   void doGet(HttpServeltRequest request , HttpServletResponse response){
    myMap.put("ipaddress", "accessTime");
   }
}

第二类是调度程序:

public class MyDailyTask implements Job {
  void executeMethod(){
  //Writing the map object to file or database login here
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(bos);
    out.writeObject(ClassServletA.myMap);
    out.flush();
    out.close();
    // Reinitialize the hashmap 
    ClassServletA.myMap=new HashMap<String,String> ();
    }
}

当调度程序(MyDailyTask.java)执行executeMethod()时,是否可以锁定或避免在调度时间段内全局修改ClassServletA.myMap Map对象。

1 个答案:

答案 0 :(得分:1)

如果您只是想确保myMap在执行executeMethod时未被修改,但您不想阻止其他线程访问它,您可以使用{{3 }}

  public class ClassServletA {
  public static final AtomicReference<Map<String,String>> myMap = new AtomicReference(new HashMap<>());

   void doGet(HttpServeltRequest request , HttpServletResponse response){
    myMap.get().put("ipaddress", "accessTime");
   }
}

public class MyDailyTask implements Job {
  void executeMethod(){
  //Writing the map object to file or database login here
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(bos);
    out.writeObject(ClassServletA.myMap.getAndSet(new HashMap<>()));
    out.flush();
    out.close();
    }
}

如果您想阻止对myMap的任何访问,请考虑使用AtomicReference。请参阅其他有关它的问题:ReadWriteLock

无论哪种方式,HashMap都不是线程安全的,并且需要适当的同步来进行并发访问。见Java Concurrency: ReadWriteLock on Variable