我正在创建 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/