Я исследовал различия между synchronized
и volatile
и написал пример без volatile, который, я считаю, эквивалентен примеру с volatile (из-за дополнительной синхронизации при извлечении)
Версия с Volatile
public class Volatile extends Super {
private volatile int xCounter;
private volatile int yCounter;
@Override
public int getXCounter() {
return this.xCounter;
}
@Override
public int getYCounter() {
return this.yCounter;
}
@Override
public void incrementXCounter() {
synchronized (getLockXCounter()) {
this.xCounter++;
}
}
@Override
public void incrementYCounter() {
synchronized (getLockYCounter()) {
this.yCounter++;
}
}
}
Версия без Volatile
public class NonVolatile extends Super {
private int xCounter;
private int yCounter;
@Override
public int getXCounter() {
synchronized (getLockXCounter()) {
return this.xCounter;
}
}
@Override
public int getYCounter() {
synchronized (getLockYCounter()) {
return this.yCounter;
}
}
@Override
public void incrementXCounter() {
synchronized (getLockXCounter()) {
this.xCounter++;
}
}
@Override
public void incrementYCounter() {
synchronized (getLockYCounter()) {
this.yCounter++;
}
}
}
Суперкласс
public abstract class Super {
private final Object lockXCounter = new Object();
private final Object lockYCounter = new Object();
protected abstract int getXCounter();
protected abstract int getYCounter();
protected abstract void incrementXCounter();
protected abstract void incrementYCounter();
Object getLockXCounter() {
return lockXCounter;
}
Object getLockYCounter() {
return lockYCounter;
}
}
В частности, Есть ли эквивалент между двумя примерами, представленными в следующих двух пунктах?
1) Производительность
2) Thread-Safety
Пожалуйста, приведите пример, показывающий отсутствие безопасности нитей, если безопасность нитей не гарантируется в одном из примеров.