我有一个程序,可以根据 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);
}
}
有什么想法吗?
您可能使用多个实例,否则在实例上同步的方法访问上不会出现同步问题。
要解决您的问题,您可以在所有实例共享的静态字段上进行同步。
在类中添加一个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()
调用产生副作用。
有可能有 2 个线程正在访问
createTable
方法,我会尝试解释一下。
这个方法定义了
synchronized
,这意味着它同步的对象是this
。
所以我的猜测是,在您的程序中,2 个线程可能会访问 createTable
,因为有两个不同的对象,每个 createTable
都同步。
因此,如果 2 个线程想要创建具有相同名称的新表 - 这是可能的。
注意:此分析是基于您提供的信息,如果您认为不太可能,请提供更多信息,我会尽力提供帮助。