对于它(以及一些娱乐价值),让我们看看什么是可行的......
我将锁对象放入包可见类的静态字段中,让我所有的默认方法共享锁。锁提供者按需为实例提供自己的锁。当实例被垃圾回收时,锁将从集合中移除。
锁提供者在第一次从实例请求它时创建一个锁,然后返回相同的锁。它看起来像这样:
final class LockProvider {
private static final WeakHashMap<Widget,Object> widgetLocks = new WeakHashMap<>();
static Object obtainLock(Widget w) {
synchronized (widgetLocks) {
return locks.computeIfAbsent(w, x -> new Object());
}
}
}
现在默认的接口方法如下所示:
public interface Widget{
default void addSomething(List<String> names) {
synchronized (LockProvider.obtainLock(this)) {
... do something
}
}
}
这样做的一个弱点是WeakHashMap
使用Object.hashcode()
和Object.equals()
。另一个是,虽然速度很快,但它并不是超高性能。尽管这种方式看起来很聪明……任何需要在私有锁上同步的方法都可以用另一种方式更好地设计。
[更新]
我最后做的是:
1)创建默认方法:
public interface Widget{
default void addSomething(List<String> something) {
... do something
}
}
2) 然后创建常规和线程安全的实现
public class WidgetImpl implements Widget{
...
}
// Threadsafe version
public class WidgetThreadsafeImpl implements Widget{
private final Object lock = new Object();
public void addSomething(List<String> something) {
synchronized(lock){
super.addSomething(something);
}
}
}
默认方法提供算法,实现可以提供线程安全或非线程安全的实现。