您将在下面看到的代码尝试实现以下目标:
从arraylist中删除最后一项
将“第1行”添加到arraylist
......依此类推。
所以,我期望的输出只是:
第0行
第1行
...
...
然而,我得到的是随机数量的“行i”,其中我也是随机的。 这是一个示例输出:
第0行
第38919行
第47726行
第54271行
然后程序卡在看似死锁的地方,即使这没有意义,因为变量'hold'只能是true或false,并且这些情况中的任何一个都应该允许其中一个线程做工作
import java.util.*;
public class Test {
static boolean held = true;
static ArrayList<String> line = new ArrayList<>();
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
int i = 0;
while(true) {
if(held) {
line.add("Line " + i);
i++;
held = false;
}
}
}
}.start();
while(true) {
if(!held) {
System.out.println( line.get(line.size() - 1) );
line.remove(line.size() - 1);
held = true;
}else continue;
}
}
}
答案 0 :(得分:6)
可能您的held
变量不是volatile
导致死锁。计算机上的不同核心将拥有自己的内存缓存,这些缓存不一定同时更新。要确保所有线程都可以看到保持的更改,您应该使其变得不稳定。您还可以使用AtomicBoolean,或同步访问代码块。
答案 1 :(得分:1)
首先,你的主要是你创建两个不同的线程,第一个线程(子)和main的线程将处理main的while循环。这意味着您正在同时运行它们,因此当每个线程使用它时,您无法确定 持有 的值。要解决此问题,您必须使用信号量或互斥量来访问 持有 进行更改。
第二件事是在你的while循环中没有任何东西可以让程序脱离它们,这就是为什么它可能会导致你无限循环。
答案 2 :(得分:0)
您可以使用两个线程同步的锁定对象,然后让每个线程在列表上执行操作,然后使用wait和notify交替唤醒另一个也会执行相同操作的线程。
答案 3 :(得分:0)
我认为在这种情况下,最好使用同步 列表而不是arraylist:
List line = Collections.synchronizedList(new ArrayList(...));