You can use 'synchronized' keyword (blocked)
class App {
int var0 = 0;
int var1 = 0;
public synchronized void apply(IntUnaryOperator f0, IntUnaryOperator f1) {
this.var0 = f0.applyAsInt(this.var0);
this.var1 = f0.applyAsInt(this.var1);
}
public synchronized int[] get() {
return new int[] {var0, var1};
}
}
or 'Lock' class (blocked)
class App {
Lock lock = new ReentrantLock();
int var0 = 0;
int var1 = 0;
public void apply(IntUnaryOperator f0, IntUnaryOperator f1) {
lock.lock();
try {
this.var0 = f0.applyAsInt(this.var0);
this.var1 = f0.applyAsInt(this.var1);
} finally {lock.unlock();}
}
public int[] get() {
lock.lock();
try {
return new int[]{var0, var1};
} finally {lock.unlock();}
}
}
or use 'AtomicReference' to immutable data structure (non-blocked)
class App {
AtomicReference<Data> data = new AtomicReference<>(new Data(0, 0));
public void apply(IntUnaryOperator f0, IntUnaryOperator f1) {
while (true) {
Data oldData = data.get();
Data newData = new Data(
f0.applyAsInt(oldData.var0),
f1.applyAsInt(oldData.var1)
);
if (data.compareAndSet(oldData, newData)) {
break;
}
}
}
public int[] get() {
Data current = data.get();
return new int[]{current.var0, current.var1};
}
static class Data {
final int var0;
final int var1;
public Data(int var0, int var1) {
this.var0 = var0;
this.var1 = var1;
}
}
}
or realize something like 'actor model' (non-blocking + with additional Thread) for writing and non-blocking atomic reading
class App {
AtomicReference<Data> data = new AtomicReference<>(new Data(0, 0));
BlockingQueue<IntUnaryOperator[]> mutateOperations
= new LinkedBlockingQueue<>();
Thread writer;
{
this.writer = new Thread(() -> {
while (true) {
try {
IntUnaryOperator[] mutateOp = mutateOperations.take();
Data oldData = data.get();
data.set(new Data(
mutateOp[0].applyAsInt(oldData.var0),
mutateOp[1].applyAsInt(oldData.var1)
));
} catch (InterruptedException e) {
break;
}
}
});
this.writer.start();
}
public void apply(IntUnaryOperator f0, IntUnaryOperator f1) {
mutateOperations.add(new IntUnaryOperator[]{f0, f1});
}
public int[] get() {
Data current = data.get();
return new int[]{current.var0, current.var1};
}
static class Data {
final int var0, var1;
public Data(int var0, int var1) {
this.var0 = var0;
this.var1 = var1;
}
}
}