java - JAVA中如何使静态方法线程安全?

标签 java multithreading thread-safety static-methods

我正在创建 Web 应用程序并遇到线程安全问题。在阅读了几个类似的问题后,我仍然对我的情况感到困惑。我正在使用 java spring 框架来设置 REST web 服务。所有请求(Person 对象的 JSON)都将传递给 checkIfGoodName 函数,如 Checker.checkIfGoodName(person)。它们都是静态方法调用。我想知道,这个函数 Checker.checkIfGoodName 线程安全吗?如果不是,如何修改代码?我有如下代码:

检查器.java

public class Checker {

    public static void checkIfGoodName(Person person){

        checkingName(Person person);

    }

    private static void checkingName(Person person){

        if(person.getName()==null){
            PersonUtils.addErrorMessage(Person person, new String("Name is empty"));
        }

    }

}

PersonUtils.java

public class PersonUtils {

     public static void addErrorMessage(Person person, String errorMessage){

         List<Message> msg = person.getMessageList();
         if(msg!=null){
             msg.add(buildMessage(errorMessage));
         }
     }

     public static void buildMessage(String errorMessage){
         if(errorMessage != null){
             Message msg = new Message();
             msg.setMsg(errorMessage);
         } 
     }

}

最佳答案

不要考虑使方法 线程安全。线程安全是关于保护数据的完整性。更具体地说,它是关于防止线程在其他线程正在更改数据的过程中访问数据。

您的PersonUtils.addErrorMessage(person, message) 方法修改属于Person 实例的List 实例。对列表的访问应该是同步的如果同一个列表可以被两个不同的线程修改,或者如果它可以被一个线程修改并被其他线程访问。

将一个项目添加到列表需要几个步骤,如果线程 A 在线程 B 执行了一些但不是所有步骤时能够看到它,则列表几乎肯定会显示为非法状态.如果两个线程同时尝试修改列表,情况会更糟:这可能会使列表处于永久的非法状态。

仍然需要同步,即使在同一 Person 实例上运行的线程实际上并未同时执行。原因是,如果没有同步,计算机硬件和操作系统不能保证一个线程在内存中所做的更改将立即对其他线程可见。但是,synchronized 可以帮到您:

在线程 B 进入 synchronized( foo) block 。

您要做的最简单的事情,如果不同的线程访问同一个 Person 实例,将是在您的 addErrorMessage(...) 方法中同步 Person 对象:

  public static void addErrorMessage(Person person, String errorMessage){
      synchronized(person) {
          List<Message> msg = person.getMessageList();
          if(msg!=null){
             msg.add(buildMessage(errorMessage));
          }
      }
  }

关于java - JAVA中如何使静态方法线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27496864/

相关文章:

java - java中使用可重入锁进行锁定同步

c++ - OpenCV OpenCL 线程安全 - 死锁(将 cv::Mat 更改为 UMat)

java - 如何添加一个计时器对象以在一个线程上每 X 秒执行一次操作,在另一个线程上每 Y 秒执行一次操作?

multithreading - 为什么javafx应用程序不是线程安全的?

java - 无法在此实例 oneliner 上实例化和调用方法

java - Java服务使用什么框架+应用服务器+开发环境?

c++ - Valgrind:使用atomic::compare_exchange_weak时,条件跳转或移动取决于未初始化的值

c - FreeBSD:如何通过PID检查进程中有多少个线程正在运行?

java - 如何在Java中Aspect类内部实现线程安全缓存?

java - 在不下载 DTD 的情况下解析 XML 文档的标准方法