Java 2个线程同时访问一个同步函数
我有一个程序,它根据cpu的内核数自动生成线程(在我的例子中是2个,因为我在VM中运行该程序) 我有一个名为createTable的函数,它在不存在的情况下创建一个表,问题是我有多个线程,因此if语句可能无法使用,我尝试使用synchronized,但得到了相同的结果Java 2个线程同时访问一个同步函数,java,multithreading,parallel-processing,Java,Multithreading,Parallel Processing,我有一个程序,它根据cpu的内核数自动生成线程(在我的例子中是2个,因为我在VM中运行该程序) 我有一个名为createTable的函数,它在不存在的情况下创建一个表,问题是我有多个线程,因此if语句可能无法使用,我尝试使用synchronized,但得到了相同的结果 public synchronized void createTable(Utils utils, String tableName, RowSerializable row) { if(!utils.getClient()
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);
}
}
有什么想法吗 可能有两个线程正在访问
createTable
方法,我将尝试解释一下
此方法定义了synchronized
,这意味着它所同步的对象是This
。
所以我猜在您的程序中,两个线程可能会访问createTable
,因为有两个不同的对象,每个createTable
都是同步的
因此,如果两个线程想要创建具有相同名称的新表,那么这是可能的
注意:此分析基于您提供的信息,如果您认为不太可能,请提供更多信息,我将尽力提供帮助。您可能会使用多个实例,否则您将不会在实例上同步的方法访问上出现同步问题。
为了解决您的问题,您可以在所有实例共享的静态字段上进行同步 在类中添加一个静态
对象
,并打开同步,应该可以解决并发访问的问题:
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()
创建了一个副作用。您能提供更多详细信息吗?如果底层对象的同一实例在线程之间共享,那么同步方法就足够了。这是您的情况吗?您创建了多少包含此代码的对象?同步将在对象级别进行。如果每个线程创建一个单独的对象,则不会进行同步。是否从两个不同的对象调用该方法?如果在这种情况下为“是”,它将锁定两个不同的对象,因此将允许两个线程访问此方法代码。或者使用类级别锁。(使该方法为静态)该方法仅从一个对象@AndrewHenle调用,但从一个不是我的代码调用,我使用的是ApacheFlinkAPI@A.Vadillo你怎么知道它是同一个对象的实例?一个快速的测试是在一个静态对象上进行同步。这可以显示您所解释的内容,更详细地说(静态)它是同一个实例,因此两个线程都尝试创建表。第一个创建了它,第二个抛出了一个异常@AxelH——如果你是指我,我在发布它的第二天就删除了我的评论,因为你说的我也会猜,我更希望看到他如何在线程之间共享同一个实例失败。当然,静态字段很简单而且有效。我认为它有效!我会继续测试这个程序。Thanks@AxelH事实上,我理解,但我不确定OP是否真的知道创建竞争条件的资源是如何实例化的。如果解决方案有效,还可以帮助OP意识到他使用了多个实例,然后研究其代码以理解。@A.Vadillo如果对您有帮助,那就太好了:)@davidxxx完全同意您的观点。在最坏的情况下,这将有助于不需要参与这些实例初始化过程的读者。