最近在看 effective java 里面有一个关于死锁的例子
其中有一处代码是调用 ExecutorService.submit() 方法返回后的 Future 对象的 get 方法
现在问题是如果不调用 get 方法就不会有死锁问题。
刚开始还理解为并不是死锁,是 get 导致线程挂起,但是把 get 方法去掉就又不会出现程序挂起这个现象。
想请教下这个 get 方法是什么机制?为什么调用后才会出现死锁问题? 看API描述的也不是很明白。(我看中文的。。。
)
API说明:
引用
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功 完成时将会返回 null。
public static void main(String[] args) {
ObservableSet set = new ObservableSet(new HashSet());
set.addObserver(new SetObserver() {
public void added(final ObservableSet s, Integer e) {
System.out.println(e);
if (e == 23){
ExecutorService executor = Executors.newSingleThreadExecutor();
final SetObserver observer = this;
try {
executor.submit(new Runnable() {
public void run() {
s.removeObserver(observer);
}
}).get(); //为什么调用get方法会产生死锁,不调就不会有死锁问题?
} catch (Exception ex) {
throw new AssertionError(ex.getCause());
} finally {
executor.shutdown();
}
}
}
});
for (int i = 0; i < 100; i++) {
set.add(i);
}
}
public class ObservableSet extends ForwardingSet {
public ObservableSet(Set s) {
super(s);
}
private final List> observers = new ArrayList>();
public void addObserver(SetObserver observer){
synchronized (observers) {
observers.add(observer);
}
}
public boolean removeObserver(SetObserver observer){
synchronized (observers) {
System.out.println("--removeObserver--");
return observers.remove(observer);
}
}
private void notifyElementAdded(E element){
synchronized (observers) {
for (SetObserver observer: observers) {
observer.added(this, element);
}
}
}
public boolean add(E element){
boolean added = super.add(element);
if (added)
notifyElementAdded(element);
return added;
}
public boolean addAll(Collection extends E> c) {
boolean result = false;
for (E element : c)
result = add(element);
return result;
}
}