gpt4 book ai didi

java - 我必须在哪里使用同步?

转载 作者:行者123 更新时间:2023-12-02 04:50:24 24 4
gpt4 key购买 nike

我做了一些研究,但找不到解决这个问题的方法。

来自此主题Synchronization, When to or not to use?我知道我可以使用synchronized,但这样做并不能解决问题。

情况是我有一个方法,其中使用Thread来创建ArrayList。在同一个Thread 中,在 BufferedReader 完成读取文件并将行添加到第一个列表后,会调用另一个方法

在第二种方法中,第一个列表用于创建第二个列表。完成所有这些后,第一个方法使用第二个列表。

这是我使用的代码,如果有不清楚的地方请询问,我会尽力提供所需的信息。

public synchronized void theBaseList() {
Thread t = new Thread() {
@override
public void run() {
try(
while((line = br.readLine()) != null) {
firstList.add(line):
}
}
nextMethod();
currentObject = (Object[]) secondList.get(0); // throws an exception
}
}
};
t.start();
<小时/>
public synchronized void nextMethod() {
Thread t1 = new Thread(){
double objectListSize = calculateObjectListLength(firstList.size());
@override
public void run() {
try {
// create Objects
secondList.add(objects);
}
}
};
t1.start();
}

当我在 nextMethod() 中使用 Thread 从第一个列表中的项目创建一个新的列表对象时,我得到一个 ArrayIndexOutOfBoundsException 说

Exception in thread "Thread-4" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

我通过在第二种方法中不使用Thread来避免这种情况,并且一切正常。

如果我确实使用 2 个线程 并使两个方法同步,它仍然会抛出异常。

是否有可能或者我应该在第二种方法中不使用Thread来解决?我认为synchronized就是为了处理这类问题。我不明白为什么它不起作用。

最佳答案

假设您的方法是在名为 Sample 的类中定义的,并且您已经创建了一个实例 mySample。这似乎就是您的代码正在做的事情:

main thread calls mySample.theBaseList() and synchronizes by locking on mySample.
theBaseList() defines thread1 and starts it.
theBaseList() exits scope, thus unlocking on mySample.

thread1 reads in the lines of a file and adds them to list1 (these operations are not synchronized)
thread1 calls mySample.nextMethod()
mySample.nextMethod() synchronizes by locking on mySample
nextMethod() defines thread2 and starts it.
nextMethod() exits scope, thus unlocking on mySample.

* thread2 sets up list2 (these operations are not synchronized)
* thread1, having returned from nextMethod() reads from list2 (these operations are not synchronized)

最后两个操作是导致竞争状况的原因。

就您而言,使用同步方法可能粒度太粗。更好的选择可能是在两个线程操作的对象上进行同步,第二个列表。

nextMethod();
synchronized(secondList) {
currentObject = (Object[]) secondList.get(0); // should no longer throw an exception
}

synchronized(secondList) {
// create Objects
secondList.add(objects);
}

编辑:

synchronized(secondList) {
nextMethod();
secondList.wait();
currentObject = (Object[]) secondList.get(0); // should no longer throw an exception
}

synchronized(secondList) {
// create Objects
secondList.add(objects);
secondList.notifyAll();
}

关于java - 我必须在哪里使用同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29291744/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com