オブジェクトを作成し、作成されたオブジェクトの数を増やすコードがあります。オブジェクトを作成してカウントを増やすコードは、カウントがオブジェクトの MAX 数に達したかどうかをチェックする if 条件によって保護されています。コードをマルチスレッドで実行すると、行の位置によってカウントがインクリメントされると判断された if 条件に違反する (つまり、影響がない) 可能性があります。これは、Java コンパイラーの最適化が原因でしょうか? コード スニペットは次のとおりです。
private BlockingQueue<WeakReference<ItemType>> items;
private final ReferenceQueue<ItemType> referenceQueue = new ReferenceQueue<ItemType>();
private final int maxSize = 10;
private final AtomicInteger numberOfCreatedObj = new AtomicInteger(0);
protected ItemType create(boolean addToCache) {
ItemType item = null;
try {
if (!hasCreatedMaxObjects()) {
// we have not reached maxSize yet.
item = getFactory().create();
// this position makes the MAX objects checking working
// Position A:
increaseCreatedObjectCount();
LOG.debug("Created new item [" + item.getId() + "]");
if (addToCache) {
LOG.debug("Add to cache the new item [" + item.getId() + "]");
addCreated(item);
}
// This position makes the MAX objects checking failed
// Position B;
//increaseCreatedObjectCount();
} else {
LOG.warn("Already reached MAX created objects " + numberOfCreatedObj.get());
}
} catch (Exception e) {
LOG.error("Error in creating a new object", e);
}
return item;
}
protected boolean hasCreatedMaxObjects() {
return getNumberOfCreatedObj().compareAndSet(getMaxSize(), getMaxSize());
}
protected void increaseCreatedObjectCount() {
getNumberOfCreatedObj().incrementAndGet();
}
protected void addCreated(ItemType item) {
items.offer(new WeakReference<ItemType>(item, referenceQueue));
}
30 スレッドでテストを実行しました。各スレッドは、作成されたオブジェクトを取得した後、100 ミリ秒間スリープします。位置 A で increaseCreatedObjectCount() が呼び出されると、コードは正常に機能し、10 (MAX) 個のオブジェクトが作成されました。位置 B で increaseCreatedObjectCount() が呼び出されると、30 個のオブジェクトが作成されました。これは、実行中のスレッドの数と同じです。
Java コンパイラーに最適化されたコードを表示するにはどうすればよいですか?
ありがとうございました。