一個快速(我認爲)併發問題:我正在Udemy.com上通過一個多線程課程,老師通過下面的代碼進行了討論。雖然他解釋了它,但我仍不確定爲什麼要創建lock1
和lock2
對象而不是鎖定在list1
和list2
上。同步:多重鎖定 - 創建鎖定對象?
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',那麼你可以簡單地同步它。使用單獨的對象可以分離關注點,並可以考慮使代碼更清晰。 – 2014-09-29 11:42:54
同意鮑里斯。有一點我會添加它,你永遠不想鎖定由getter返回的字段。因此,通過將鎖定與用於不同目的的任何字段隔離,可以消除這種可能性。 – 2014-09-29 11:47:22
感謝@BoristheSpider和@John B.爲什麼只鎖定'final'變量?爲什麼不使用getters? – 2014-09-29 12:10:28