2 个线程同时访问同步函数

问题描述 投票:0回答:2

我有一个程序,可以根据 CPU 核心的数量自动生成线程(在我的例子中是 2 个,因为我在虚拟机中运行该程序)

我有一个名为 createTable 的函数,如果它不存在,它会创建一个表,问题是我有多个线程,因此 IF 语句可能没用,我尝试使用同步,但得到了相同的结果

public synchronized void createTable(Utils utils, String tableName, RowSerializable row) {
   if(!utils.getClient().tableExists(tableName)) {
       this.table = utils.generateTable(tableName, row);
       this.fieldsNames = utils.getNamesOfColumns(table);
   }
}

有什么想法吗?

java multithreading parallel-processing
2个回答
3
投票

您可能使用多个实例,否则在实例上同步的方法访问上不会出现同步问题。

要解决您的问题,您可以在所有实例共享的静态字段上进行同步。

在类中添加一个static

Object
,并开启同步,应该可以解决访问并发的问题:

   public class YourClassThatHasTheProblem {
   ...
   private static final Object lock = new Object();
   ... 
    public void createTable(Utils utils, String tableName, RowSerializable row) {
      synchronized (lock) {
        if(!utils.getClient().tableExists(tableName)) {
          this.table = utils.generateTable(tableName, row);
          this.fieldsNames = utils.getNamesOfColumns(table);
         }
       }
  }
 ...
}

如果它不能解决您的问题,则意味着问题不仅仅来自代码同步,而是因为您在另一个类或方法中执行了类似的处理,并且与此调用不同步。因此,它会通过

createTable()
调用产生副作用。


1
投票

有可能有 2 个线程正在访问

createTable
方法,我会尝试解释一下。

这个方法定义了

synchronized
,这意味着它同步的对象是
this
。 所以我的猜测是,在您的程序中,2 个线程可能会访问
createTable
,因为有两个不同的对象,每个
createTable
都同步。

因此,如果 2 个线程想要创建具有相同名称的新表 - 这是可能的。

注意:此分析是基于您提供的信息,如果您认为不太可能,请提供更多信息,我会尽力提供帮助。

© www.soinside.com 2019 - 2024. All rights reserved.