【发布时间】:2014-09-29 19:47:08
【问题描述】:
一个快速(我认为)并发问题:我正在 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,那么您可以简单地对其进行同步。使用单独的对象将关注点分开,并且可以考虑使代码更清晰。 -
同意鲍里斯。有一点我要补充一点,您永远不想锁定由 getter 返回的字段。因此,通过将锁与用于不同目的的任何字段隔离开来,您就可以消除这种可能性。
-
感谢@BoristheSpider 和@John B。为什么只锁定
final变量?为什么不使用 getter? -
JVM 不会让多个线程同时在同一个对象上同步。两个线程可以同时进入
synchronized(foo)块吗?绝对地!因为一个线程可以进入块,然后将 foo 更改为引用不同的对象,然后另一个线程出现并在另一个对象上同步。当这种情况发生时,它通常是一个错误。制作 foofinal可以帮助你避免这个错误。
标签: java multithreading locking