我一直在阅读,我发现无论在哪里,代码都是在代码上创建的,例如作为成员变量,局部变量或类变量,它们总是在Java中的堆空间内创建。我想知道在这个例子中,执行ArrayList
时创建的doSomething()
是否会在生成并发问题的线程之间共享,或者在堆中创建两个不同的实例。
public ArrayList<T> doSomething(){
ArrayList<T> list = new ArrayList<>();
//...Add content to the list
return list;
}
public void printList(ArrayList<T> list){
for(T element: list)
System.out.println(element);
}
Thread thread1 = new Thread(new Runnable{
public void run(){
printList(doSomething());
}
}
Thread thread2 = new Thread(new Runnable{
public void run(){
printList(doSomething());
}
}
thread1.start();
thread2.start();
答案 0 :(得分:5)
在这段代码中
public ArrayList<T> doSomething(){
ArrayList<T> list = new ArrayList<>();
//...Add content to the list
return list;
}
和
thread1.start();
thread2.start();
你创建了两个ArrayList
,因此两个线程之间不会有任何“共享”,因为它们完全是两个不同的对象。
答案 1 :(得分:1)
在您发布的代码中,创建了两个不同的ArrayList
实例。所以你实际上在处理两个独立的对象实例。
但是,如果您要在线程之间共享实例,则需要注意线程安全。
答案 2 :(得分:1)
在代码上创建对象,例如作为成员变量,局部变量或类变量,它们总是在Java
中的堆空间内创建
@Albus'回答是正确的。但是,要添加一些细节,所有对象都是在堆上创建的,但在您的情况下:
public ArrayList<T> doSomething() {
ArrayList<T> list = new ArrayList<>();
...
对象list
的引用仅存储在堆栈中。 ArrayList
对象本身位于堆上,但由于list
位于堆栈上,因此不同的线程不可能访问此列表,从而产生并发问题。如果两个线程以某种方式访问同一个ArrayList
对象,要么是因为它是共享的static
字段,要么是它被传入,那么你需要担心同步和并发。