gpt4 book ai didi

Java : updates to variables before and after Thread. 开始()

转载 作者:行者123 更新时间:2023-12-03 13:23:20 25 4
gpt4 key购买 nike

我有两个类

classA {
private ArrayList<String> list = new ArrayList();

void addString(String s){
list.add(s);
}

void start(){
new ClassB(list).start();
}
}

classB extends Thread{
ArrayList<String> s;

public ClassB(ArrayList<String> s) { this.s = s; }

void run(){
for (String s1 : s){
// print s1
}
}
}
现在当我写代码时
ClassA A = new ClassA();
A.addString("1");
A.addString("2");
A.addString("3");
A.start();
我希望 classB 中的 run() 打印列表中的所有元素。在这种情况下,即 (1, 2, 3)。
这总是默认的还是我们需要应用多线程概念来实现它?
如果列表是非 volatile 的怎么办?新线程可以看到所有元素(1,2,3)
如果我在 A.start() 之后添加另一个元素(比如 A.addString("4") ),那么我应该怎么做才能让新线程打印所有 4 个元素?

最佳答案

如果添加所有元素 之前 启动另一个线程(ClassB)是安全的。 JLS §17.4.4说:

An action that starts a thread synchronizes-with the first action in the thread it starts.


并且 synchronizes-with 在 §17.4.5 中定义:

If an action x synchronizes-with a following action y, then we also have hb(x, y).


(hb(x, y) = x 发生在 y 之前)
所以这保证了添加元素发生在读取和打印元素之前。
但是,使用您当前的代码,如果您从主线程添加元素 之后 您启动了另一个线程,那么您将没有线程安全保证并且行为未定义。另一个线程可能会看到添加的元素,但也看不到它们,甚至可能抛出异常,因为它看到了 ArrayList 的数据。处于不一致的状态。

What if I add another element after A.start() (say A.addString("4") ), then what should I do to make new thread print all 4 elements?


这很难用您的示例代码回答,因为不清楚代码应该如何表现:
  • 另一个线程(ClassB)是否应该无限期地等待新元素?那么一种解决方案可能是使用 BlockingQueue或使用某种信号并使用线程安全集合(或同步访问 ArrayList)是必需的。
  • 如果另一个线程(ClassB)在添加新元素之前完成打印旧元素,是否允许错过新元素?然后只需要使用线程安全的集合(或同步访问 ArrayList)是必要的。
  • ...
  • 关于Java : updates to variables before and after Thread. 开始(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63744591/

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