当前位置: 首页 > 知识库问答 >
问题:

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

丁安宜
2023-03-14

我有两个类,第一个类(ClassServletA.java)是HttpServlet,它在HashMap中存储IP地址和访问时间,我想每天备份数据库中的HashMap,所以我计划任务并将静态HashMap对象存储在数据库中,然后重新初始化HashMap(在存储在数据库中之后)。

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

 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)执行执行方法()时,是否可以在调度时间段内全局锁定或避免修改ClassServletA. myMap Map对象。

共有1个答案

笪栋
2023-03-14

如果您只想确保在执行executeMethod时不修改myMap,但又不想阻止其他线程对它的访问,您可以使用AtomicReference

  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的任何访问,请考虑使用ReadWriteLock。请参阅关于它的其他问题:Java并发性:变量上的ReadWriteLock

无论哪种方式,HashMap都不是线程安全的,需要适当的同步才能进行并发访问。请参阅Java多线程访问静态变量

 类似资料:
  • 问题内容: 假设我有一些Java代码: 如果一个线程正在初始化SomeClass的对象,并且在第二个线程想要再次加载SomeClass的过程中正在初始化静态块中的值,那么该静态块会怎样?即使第一个线程未完成,第二个线程是否仍假设它已初始化而忽略了它?还是发生其他事情? 问题答案: 如果第一个线程尚未完成对SomeClass的初始化,则第二个线程将阻塞。 Java语言规范的12.4.2节中对此进行了

  • 我正在使用的SMS网关来响应客户传入的短信。 但是,我的处理需要相当长的时间(大约20秒),在此期间,我从Twilio收到一个超时。 我在想一个防止超时的方法。我怎样才能加快处理时间?耗时最长的部分是我上传一些图像。我在想我可以在不同的线程中启动这个过程。我的服务器只有一个核心,那么多线程会有好处吗?

  • 现在遇到一个项目,uniapp开发的微信小程序,之前的所有页面都没有使用scope将css样式私有化,导致css属性全局污染了,现在要开发后续的功能,如何在后续的开发中避免之前css的样式污染? 之前开发的内容不能使用scope将css私有化,因为一旦私有化可能会对某些页面造成影响,现在的情况就是之前的内容不能动,在此基础上开发。 目前想到的办法是在后续开发的功能中,所有的css类名名全部使用当前

  • 问题内容: 从MDN for NodeList: 在某些情况下,NodeList是一个实时集合,这意味着DOM中的更改会反映在集合中。例如,Node.childNodes处于活动状态: 在其他情况下,NodeList是静态集合,这意味着DOM中的任何后续更改都不会影响集合的内容。document.querySelectorAll返回一个静态NodeList。 所以....有点烦!是否有任何关于哪些

  • 问题内容: 我有一个关于可变范围的问题。 例如: 现在,我创建两个线程,并为每个线程创建一个实例。 当我在每个线程中调用时,可以保证线程安全吗? 本地变量存储在哪里?每个线程的堆栈?堆空间? PS我知道在这种情况下,静态是毫无意义的。我在我们的旧代码中找到了它;我只是想确定我所知道的! 问题答案: 局部变量存储在每个线程自己的堆栈中。这意味着局部变量永远不会在线程之间共享。这也意味着所有本地原始变