<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.17.0</version> </dependency>
private Integer id = Integer.valueOf(0); public void updateId(final Integer localId) { this.id = localId; System.out.println("localId: " + localId + " / id:" + this.id); }The problem with this example is if multiple threads call this method, the value of the instance variable "id" that we print at the end of the method can be different from the value of the parameter "localId".
localId: 2 / id:3 localId: 4 / id:3 localId: 1 / id:3 localId: 0 / id:3 localId: 3 / id:3
public class SampleReentrantLock { private final ReentrantLock lock = new ReentrantLock(); private Integer id = Integer.valueOf(0); public void updateId(final Integer localId) { try { lock.lock(); this.id = localId; // simulate a time-consuming code try { Thread.sleep(500l); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("localId: " + localId + " / id:" + this.id); } finally { lock.unlock(); } } public static void main(String[] args) throws InterruptedException { final String poolName = "_newFixedThreadPool"; final BasicThreadFactory basicThreadFactory = new BasicThreadFactory.Builder().namingPattern(poolName).daemon(true).build(); final ExecutorService executorService = Executors.newFixedThreadPool(5, basicThreadFactory); final SampleReentrantLock instance = new SampleReentrantLock(); IntStream.iterate(0, i -> i + 1).limit(5).forEach(t -> executorService.execute(() -> { try { // wait (random time) before calling the update method Thread.sleep(new Random().nextInt(500) + 1); } catch (Exception e) { e.printStackTrace(); } instance.updateId(t); })); executorService.awaitTermination(10000l, TimeUnit.MILLISECONDS); executorService.shutdown(); } }Output:
localId: 2 / id:2 localId: 0 / id:0 localId: 1 / id:1 localId: 4 / id:4 localId: 3 / id:3