第一个问题:
import java.util.LinkedList;
import java.util.List;
public class Example implements Runnable {
private static LinkedList<ListEntry> objList;
public static class ListEntry {
public int var = -1;
public ListEntry(List<ListEntry> objList, int var) {
synchronized (objList) {
objList.add(this);
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {}
this.var = var;
}
}
public static void main(String[] args) {
objList = new LinkedList<>();
new ListEntry(objList, 1);
for (int i=0; i < 100; i++) {
new Thread(new Example()).start();
}
}
public void run() {
for (int i=0; i < 1000; i++) {
ListEntry lastEntry;
synchronized (objList) {
lastEntry = objList.getLast();
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {}
int lastVar = lastEntry.var;
new ListEntry(objList, lastVar + 1);
System.out.println(lastVar);
if (lastVar < 0)
throw new RuntimeException("lastVar = " + lastVar);
}
}
}
如果您运行此代码,则会不时抛出 RuntimeException,因为添加到列表中的最后一个对象尚未完成构造,因此它的 var 实例将具有初始值 -1。这可能是因为您在构造函数中“泄漏”了对象引用 (this)。想不出更好的例子。
第二个问题:同步方法保证它在该方法的任何后续调用发生之前完成(已经发生)。不知道怎么形容更好。