Java 如何使两个线程轮流修改arraylist?
下面您将看到的代码试图实现以下目标:Java 如何使两个线程轮流修改arraylist?,java,multithreading,arraylist,Java,Multithreading,Arraylist,下面您将看到的代码试图实现以下目标: 将“第0行”添加到arraylist中 打印arraylist中的最后一项,即“第0行” 从arraylist中删除最后一项 将“第1行”添加到arraylist中 打印arraylist中的最后一项,即“第1行” 从arraylist中删除最后一项 ……等等,没完没了 因此,我期望的结果很简单: 第0行 第1行 然而,我得到的是一个随机数量的“线I”,其中我也是随机的。 以下是一个示例输出: 第0行 第38919行 第47726行 第54271行
- 将“第0行”添加到arraylist中
- 打印arraylist中的最后一项,即“第0行”
- 从arraylist中删除最后一项
- 将“第1行”添加到arraylist中
- 打印arraylist中的最后一项,即“第1行” 从arraylist中删除最后一项
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;
}
}
}
import java.util.*;
公开课考试{
静态布尔值=真;
静态ArrayList行=新建ArrayList();
公共静态void main(字符串[]args){
新线程(){
@凌驾
公开募捐{
int i=0;
while(true){
如果(举行){
行。添加(“行”+i);
i++;
保持=假;
}
}
}
}.start();
while(true){
如果(!保持){
System.out.println(line.get(line.size()-1));
line.remove(line.size()-1);
保持=正确;
}否则继续;
}
}
}
您可以使用两个线程同步的锁对象,然后让每个线程在列表上执行它们的操作,然后使用wait和notify交替唤醒另一个线程,该线程也会执行相同的操作。可能是您的hold
变量不是volatile
导致了死锁。计算机上的不同内核将有自己的内存缓存,不一定同时更新。要确保对保持的更改对所有线程都可见,应将其设置为易失性。您还可以使用AtomicBoolean,或同步对代码块的访问。我认为在这种情况下,最好使用同步的列表,而不是arraylist:
List line = Collections.synchronizedList(new ArrayList(...));
首先,在main中创建两个不同的线程,第一个线程(子线程)和main的线程,它们将处理main的while循环。这意味着您同时运行它们,因此您无法确定当每个线程使用它时,hold的值是多少。要解决这个问题,您必须使用信号量或互斥来访问hold进行更改
第二件事是,在while循环中,没有任何东西可以使程序脱离它们,这就是为什么它可能会导致无限循环。我在ideone上运行了这个程序,输出与您预期的一样。所以这一定是平台相关的问题。尝试将
volatile
添加到保持变量。您可以尝试使用信号灯
@Martijn-courtaux制作“保持”volatile,谢谢!此行为在@VGR“编译器可以对任一线程中的指令进行重新排序,但这不会影响该线程的独立执行”-现在,我的程序的行为已得到解释,谢谢!