I try change and get local variable with lambda. I know I should use effectively final for local variables in lambda. When I use AtomicReference local variable changing failed:
public class Lamb {
public static void main(String[] args) throws InterruptedException {
Lamb lamb = new Lamb();
GlobalL globalL = new GlobalL();
lamb.a(globalL);
for (int i = 0; i < 100; i++) {
new Thread(() -> {
globalL.printSum();
}).start();
}
Thread.sleep(3000);
System.out.println("--------After Work--------");
globalL.printSum();
}
public void a(GlobalL globalL) {
AtomicReference<Integer> number = new AtomicReference<>(0);
Work work = () -> {
number.getAndSet(number.get() + 1);
return number.get();
};
globalL.setWork(work);
}
}
class GlobalL {
private Work work;
public void printSum() {
System.out.println(work.getAndInc());
}
public void setWork(Work work) {
this.work = work;
}
}
interface Work {
int getAndInc();
}
Output different every time:
public void a(GlobalL globalL) {
Integer[] number = {1};
Work work = () -> {
number[0]++;
return number[0];
};
globalL.setWork(work);
}
Output every time:
--------After Work--------
102
1) The code:
number.getAndSet(number.get() + 1);
return number.get();
is a critical section since there is a couple of operations that are not atomically performed. That's why you get different results. To eliminate the critical section:
public void a(GlobalL globalL) {
AtomicInteger number = new AtomicInteger(0);
Work work = () -> {
return number.incrementAndGet();
};
globalL.setWork(work);
}
2) You can't (see this or the official tutorial on Anonymous Classes)
3) IMO, it should be a separate question. To put it in few words, lambdas are just syntactic sugar and they get compiled into anonymous inner classes.
As for why array works correctly?
question, the answer is: it doesn't for the same reason: ++ is not an atomic operator
To prove it, just increase the number of threads to, let's say, 1000:
for (int i = 0; i < 1000; i++) {
new Thread(() -> {
globalL.printSum();
}).start();
}
I'm getting:
--------After Work-------- 972