import java.lang.invoke.VarHandle; import java.lang.invoke.MethodHandles; // assumes that each set function is called only once sclass LongPairCollector { volatile long a; volatile long b; volatile int counter; // statically get var handles private static final VarHandle vhCounter; static ctex { var l = MethodHandles.lookup(); vhCounter = l.findVarHandle(LongPairCollector.class, "counter", int.class); } void setA(long a) { this.a = a; incCounter(); } void setB(long b) { this.b = b; incCounter(); } LongConsumer setA aka setterForA() { ret a -> setA(a); } LongConsumer setB aka setterForB() { ret b -> setB(b); } private void incCounter() { if (((int) vhCounter.getAndAdd(this, 1))+1 == 2) complete(a, b); } // can override or swap swappable void complete(long a, long b) {} }