Как подсказано в комментариях, для соблюдения указанного требования следует использовать AtomicInteger
в качестве контейнера значения и его методы getAndIncrement() / get()
, либо использовать статическую переменную (на уровне класса), или же объявить локальную переменную как массив:
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class MyClass {
static int done = 0;
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(1);
int[] arr = {0};
AtomicInteger at = new AtomicInteger(0);
for (int i = 0; i < 5; i++) {
executorService.submit((Runnable) () -> {
System.out.println("Thread " + Thread.currentThread().getName() + " done, values changed: atomic=" + at.getAndIncrement() + "; static=" + done++ + "; arr=" + arr[0]++);
});
}
executorService.shutdown();
System.out.println("Main thread '" + Thread.currentThread().getName() + "': atomic: " + at.get() + "; static: " + done + "; arr: " + arr[0]);
}
}
Результаты:
Thread pool-1-thread-1 done, values changed: atomic=0; static=0; arr=0
Main thread 'main': atomic: 0; static: 0; arr: 0
Thread pool-1-thread-1 done, values changed: atomic=1; static=1; arr=1
Thread pool-1-thread-1 done, values changed: atomic=2; static=2; arr=2
Thread pool-1-thread-1 done, values changed: atomic=3; static=3; arr=3
Thread pool-1-thread-1 done, values changed: atomic=4; static=4; arr=4
При такой реализации главный поток завершает выполнение раньше, чем успеют завершиться потоки, запущенные при помощи ExecutorService
.
Если нужно, чтобы главный поток main
дождался окончания остальных потоков, следует использовать ExecutorService::awaitTermination
:
public class MyClass {
static int done = 0;
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
int[] arr = {0};
AtomicInteger at = new AtomicInteger(0);
for (int i = 0; i < 5; i++) {
executorService.submit((Runnable) () -> {
System.out.println("Thread " + Thread.currentThread().getName() + " done, values changed: atomic=" + at.getAndIncrement() + "; static=" + done++ + "; arr=" + arr[0]++);
});
}
executorService.shutdown();
executorService.awaitTermination(100L, TimeUnit.MILLISECONDS);
System.out.println("Main thread '" + Thread.currentThread().getName() + "': atomic: " + at.get() + "; static: " + done + "; arr: " + arr[0]);
}
}
Thread pool-1-thread-1 done, values changed: atomic=0; static=0; arr=0
Thread pool-1-thread-1 done, values changed: atomic=1; static=1; arr=1
Thread pool-1-thread-1 done, values changed: atomic=2; static=2; arr=2
Thread pool-1-thread-1 done, values changed: atomic=3; static=3; arr=3
Thread pool-1-thread-1 done, values changed: atomic=4; static=4; arr=4
Main thread 'main': atomic: 5; static: 5; arr: 5