我想知道下面两个示例类有什么功能差异。哪种风格应该优于另一种风格以及原因。
public class MyQueue {
private Queue<Abc> q;
public MyQueue() {
q = Collections.synchronizedList(new LinkedList<Abc>());
}
public void put(Abc obj) {
q.add(obj);
}
public Abc get() {
return q.remove();
}
}
或者
public class MyQueue {
private Queue<Abc> q;
public MyQueue() {
q = new LinkedList<Abc>();
}
public synchronized void put(Abc obj) {
q.add(obj);
}
public synchronized Abc get() {
return q.remove();
}
}
我的看法是 - 就类中的这么多功能而言,两者都可以完美地工作,只是个人喜好问题。
如果有更多差异,请告诉我。
最佳答案
主要的架构差异是第二个实现将同步监视器(对象本身)暴露给外界。这意味着每个人都可能获取您用于内部同步的相同锁:
MyQueue myQueue = new MyQueue(); // a shared instance
synchronized(myQueue) {
// No one else can call synchronized methods while you're here
}
它可能会带来好处或导致问题,具体取决于您的类用例。
第一个实现隐藏了同步的细节,这一事实为您在将来添加新功能提供了更大的灵 active (例如,您可以在 put()
中添加一些未同步的代码和 get()
方法(如果需要的话)),但会带来一个小问题,那就是在列表周围有一个额外的层。
否则,所提供的功能没有任何区别。
PS:不要忘记将 final
添加到 q
声明中。否则你的类不能保证所谓的安全发布并且不能被称为完全线程安全。
关于java - 定义线程安全类的两种方式的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39263746/