I have two classes
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
}
}
}
Now when I write code as
ClassA A = new ClassA();
A.addString("1");
A.addString("2");
A.addString("3");
A.start();
I want run() in classB to print all elements in list. i.e (1, 2, 3) in this case.
Is this always default or do we need to do apply multi threading concepts to make it happen?
What if list is non-volatile? Can new thread see all the elements (1,2,3)
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?
If you add all elements before starting the other thread (ClassB) it is safe. The JLS §17.4.4 says:
An action that starts a thread synchronizes-with the first action in the thread it starts.
And synchronizes-with is defined in §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)
So this guarantees that adding the elements happens-before reading and printing the elements.
However, with your current code, if you add elements from the main thread after you started the other thread, then you will have no thread-safety guarantees and the behavior is undefined. The other thread might see the added elements, but it could also not see them or possibly even throw an exception because it sees the data of the ArrayList
in an inconsistent state.
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?
This is difficult to answer with your example code because it is not clear how the code should behave: