1) Код:
number.getAndSet(number.get() + 1);
return number.get();
является критическим разделом, поскольку существует пара операций, которые не выполняются атомарно. Вот почему вы получаете разные результаты. Чтобы исключить критический раздел:
public void a(GlobalL globalL) {
AtomicInteger number = new AtomicInteger(0);
Work work = () -> {
return number.incrementAndGet();
};
globalL.setWork(work);
}
2) Вы не можете (см. этот или официальный учебник по анонимным классам )
3) ИМО, это должен быть отдельный вопрос. Короче говоря, лямбды - это просто синтаксис c сахара и они скомпилированы в анонимные внутренние классы.
Что касается вопроса why array works correctly?
, то ответ: это не так t по той же причине: ++ не является атомом c оператором Чтобы доказать это, просто увеличьте число потоков, скажем до 1000:
for (int i = 0; i < 1000; i++) {
new Thread(() -> {
globalL.printSum();
}).start();
}
Я получаю:
-------- После работы -------- 972