Java :更新 Thread.start() 前后的变量
Java : updates to variables before and after Thread.start()
我有两个类
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 中的 运行() 打印列表中的所有元素。即本例中的 (1, 2, 3)。
这始终是默认设置还是我们需要应用多线程概念才能实现?
如果列表是非易失性的呢?新线程能否看到所有元素 (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 happens-before y)
所以这保证添加元素happens-before读取和打印元素
但是,对于您当前的代码,如果您在启动另一个线程之后从主线程添加元素,那么您将没有 thread-safety 保证并且行为未定义。另一个线程 可能 看到添加的元素,但它也可能看不到它们,甚至可能抛出异常,因为它看到 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 或使用某种信号并使用 thread-safe 集合(或同步访问 ArrayList)是必需的。
- 是否允许另一个线程 (ClassB) 错过新元素,以防它在添加新元素之前完成旧元素的打印?然后只需要使用 thread-safe 集合(或同步访问 ArrayList)。
- ...
我有两个类
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 中的 运行() 打印列表中的所有元素。即本例中的 (1, 2, 3)。
这始终是默认设置还是我们需要应用多线程概念才能实现?
如果列表是非易失性的呢?新线程能否看到所有元素 (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 happens-before y)
所以这保证添加元素happens-before读取和打印元素
但是,对于您当前的代码,如果您在启动另一个线程之后从主线程添加元素,那么您将没有 thread-safety 保证并且行为未定义。另一个线程 可能 看到添加的元素,但它也可能看不到它们,甚至可能抛出异常,因为它看到 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 或使用某种信号并使用 thread-safe 集合(或同步访问 ArrayList)是必需的。
- 是否允许另一个线程 (ClassB) 错过新元素,以防它在添加新元素之前完成旧元素的打印?然后只需要使用 thread-safe 集合(或同步访问 ArrayList)。
- ...