동시성 질문 : 저는 Udemy.com에서 멀티 스레딩 과정을 밟을 것이며, 교사는 아래 코드를 통해 대화했습니다. 그는 설명했지만 여전히 list1
및 list2
에 잠글 때가 아니라 lock1
및 lock2
개체를 만드는 이유가 확실하지 않습니다.동기화 : 다중 잠금 - 잠금 개체 만들기?
App.java :
public class App {
public static void main(String[] args) {
Worker worker = new Worker();
worker.main();
}
}
Worker.java : 그에 대한 의욕을 생각하지 않는다
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Worker {
private Random random = new Random();
private Object lock1 = new Object();
private Object lock2 = new Object();
private List<Integer> list1 = new ArrayList<Integer>();
private List<Integer> list2 = new ArrayList<Integer>();
public void stageOne() {
synchronized (lock1) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list1.add(random.nextInt(100));
}
}
public void stageTwo() {
synchronized (lock2) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list2.add(random.nextInt(100));
}
}
public void process() {
for(int i=0; i<1000; i++) {
stageOne();
stageTwo();
}
}
public void main() {
System.out.println("Starting ...");
long start = System.currentTimeMillis();
Thread t1 = new Thread(new Runnable() {
public void run() {
process();
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
process();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Time taken: " + (end - start));
System.out.println("List1: " + list1.size() + "; List2: " + list2.size());
}
}
이유는 없습니다. 실제로'final' 변수에만 동기화해야합니다. 'List'를'final'으로 표시 할 수 있다면 간단히 동기화 할 수 있습니다. 별도의 객체를 사용하면 염려가 분리되고 코드가 명확 해지는 것으로 간주 될 수 있습니다. –
Boris와 (과) 일치합니다. 한 포인트는 내가 getter에 의해 리턴 된 필드를 잠그고 싶지 않다는 것을 추가 할 것이다. 따라서 다른 용도로 사용되는 필드에서 잠금을 분리하면 이러한 가능성이 없어집니다. –
감사합니다. @BoristheSpider와 @John B. 왜 'final' 변수에만 고정됩니까? 왜 getter를 사용하지 않습니까? –