[英]Synchronization: multiple locks - create lock objects?
一个快速的(我认为)并发问题:我正在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
。
如果有问题的列表是从外部接受的,或者是通过某种方法暴露给外部的,那么单独的锁对象的好处就变得更加明显:将您的锁暴露给外来代码永远不是一个好主意,因为外来代码可以然后单独使用它们进行锁定,从而破坏您自己的使用模式。
如果列表严格保密,那么它们的监视器将可用于内部锁定; 但是,以后对列表上的访问策略进行更改可能会无意中影响锁定策略。 因此,从私人锁开始也可以避免将来出现任何错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.