java - 这个静态方法是线程安全的还是需要同步

标签 java multithreading concurrency thread-safety

我有一个实用程序类,它有一个静态方法来修改输入数组列表的值。该静态方法由调用者调用。调用者用于处理 Web 服务请求。对于每个请求(每个线程),调用者都会创建一个新的 ArrayList 并调用静态方法。

public class Caller{

   public void callingMethod(){

     //Get Cloned criteria clones a preset search criteria that has place holders for values and returns a new ArrayList of the original criteria. Not included code for the clone
     ArrayList<Properties> clonedCriteria = getClonedCriteria();

     CriteriaUpdater.update(clonedCriteria , "key1", "old_value1", "key1_new_value");
     CriteriaUpdater.update(clonedCriteria , "key2", "old_value2", "key2_new_value");

    //do something after the this call with the modified criteria arraylist
   }

}

public class CriteriaUpdater
{
    //updates the criteria, in the form of array of property objects, by replacing the token with the new value passed in
    public static void update(ArrayList<Properties> criteria, String key, String token, String newValue)
    {
        for (Properties sc: criteria)
        {
            String oldValue = sc.getProperty(key);
            if ((oldValue != null) && (oldValue.equals(token))) 
                sc.setProperty(key, newValue);
        }
    }
}

这就是克隆条件的方式:

public synchronized static ArrayList<Properties> cloneSearchCriteria(ArrayList<Properties> criteria) { 
  if (criteria == null) return null; 
  ArrayList<Properties> criteriaClone = new ArrayList<Properties>(); 
  for (Properties sc : criteria) { 
    Properties clone = new Properties(); 
    Enumeration propertyNames = sc.propertyNames(); 
    while (propertyNames.hasMoreElements()) { 
      String key = (String) propertyNames.nextElement(); 
      clone.put(key, (String) sc.get(key)); 
    } 
    criteriaClone.add(clone);
  } 
  return criteriaClone; 
}

鉴于上述定义,通过不同步静态方法,它仍然能够正确处理并发方法调用。我的理解是我必须同步此方法以实现并发,但想确认一下。 我知道每个线程都会有自己的堆栈,但对于静态方法来说,它对所有线程都是通用的 - 所以在这种情况下,如果我们不同步,是否会导致问题? 感谢建议和任何更正。

谢谢

最佳答案

您遇到竞争条件问题。至少底层 Properties 数据结构永远不会被损坏,但它可能具有不正确的值。特别是,此部分中可以有任意数量的线程,这意味着最终值可以是任何线程中的任何值。

        String oldValue = sc.getProperty(key);
        if ((oldValue != null) && (oldValue.equals(token))) 
            sc.setProperty(key, newValue);

我假设您的列表永远不会改变,但如果是这样,您必须同步。您可以锁定类,但锁定您正在更改的集合可能是更好的选择。

关于java - 这个静态方法是线程安全的还是需要同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35231730/

相关文章:

java - 多个线程调用@Cacheable 方法。 Spring 缓存(3.2.6)允许所有线程进入方法

java - java中的迭代和for循环哪个更好?

java - 如何用Java获取上传/下载速度

java - 使用输入 Excel 中的更新更新 Jar 文件

ios - Swift GCD 中的持久线程

java - java中数组的并发更新

django - 如何修复 Django 的 get_or_create() 并发导致数据重复

java - 使用 JDBC 结果集更新行时出现问题

c++ - 为 OpenMP 函数创建别名 ||部分禁用 openMP

multithreading - Clojure - 有效地同时增加列表中的数字