diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGenerator.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGenerator.java index 97d44e5156..26354de0a9 100644 --- a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGenerator.java +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGenerator.java @@ -1,11 +1,12 @@ package com.baeldung.concurrent.mutex; public class SequenceGenerator { + private int currentValue = 0; - public int getNextSequence() throws InterruptedException { + public int getNextSequence() { currentValue = currentValue + 1; - Thread.sleep(500); return currentValue; } + } diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingMonitor.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingMonitor.java index 30c8da4865..2824237e24 100644 --- a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingMonitor.java +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingMonitor.java @@ -4,15 +4,16 @@ import com.google.common.util.concurrent.Monitor; public class SequenceGeneratorUsingMonitor extends SequenceGenerator { - private Monitor monitor = new Monitor(); + private Monitor mutex = new Monitor(); @Override - public int getNextSequence() throws InterruptedException { - monitor.enter(); + public int getNextSequence() { + mutex.enter(); try { return super.getNextSequence(); } finally { - monitor.leave(); + mutex.leave(); } } + } diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingReentrantLock.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingReentrantLock.java index 85ce780bda..d57b0c4a52 100644 --- a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingReentrantLock.java +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingReentrantLock.java @@ -7,7 +7,7 @@ public class SequenceGeneratorUsingReentrantLock extends SequenceGenerator { private ReentrantLock mutex = new ReentrantLock(); @Override - public int getNextSequence() throws InterruptedException { + public int getNextSequence() { try { mutex.lock(); return super.getNextSequence(); @@ -15,4 +15,5 @@ public class SequenceGeneratorUsingReentrantLock extends SequenceGenerator { mutex.unlock(); } } + } diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSemaphore.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSemaphore.java index fdece049e6..50f2538646 100644 --- a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSemaphore.java +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSemaphore.java @@ -7,12 +7,15 @@ public class SequenceGeneratorUsingSemaphore extends SequenceGenerator { private Semaphore mutex = new Semaphore(1); @Override - public int getNextSequence() throws InterruptedException { + public int getNextSequence() { try { mutex.acquire(); return super.getNextSequence(); + } catch (InterruptedException e) { + throw new RuntimeException("Exception in critical section.", e); } finally { mutex.release(); } } + } diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedBlock.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedBlock.java index d485eae21c..9933c302cb 100644 --- a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedBlock.java +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedBlock.java @@ -2,9 +2,11 @@ package com.baeldung.concurrent.mutex; public class SequenceGeneratorUsingSynchronizedBlock extends SequenceGenerator { + private Object mutex = new Object(); + @Override - public int getNextSequence() throws InterruptedException { - synchronized (this) { + public int getNextSequence() { + synchronized (mutex) { return super.getNextSequence(); } } diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedMethod.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedMethod.java index 441b33dc43..6de8725d73 100644 --- a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedMethod.java +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedMethod.java @@ -3,7 +3,7 @@ package com.baeldung.concurrent.mutex; public class SequenceGeneratorUsingSynchronizedMethod extends SequenceGenerator { @Override - public synchronized int getNextSequence() throws InterruptedException { + public synchronized int getNextSequence() { return super.getNextSequence(); } diff --git a/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/mutex/MutexUnitTest.java b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/mutex/MutexUnitTest.java index 620179800a..462f910718 100644 --- a/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/mutex/MutexUnitTest.java +++ b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/mutex/MutexUnitTest.java @@ -1,7 +1,7 @@ package com.baeldung.concurrent.mutex; import java.util.ArrayList; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -12,59 +12,58 @@ import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; -import com.baeldung.concurrent.mutex.SequenceGenerator; -import com.baeldung.concurrent.mutex.SequenceGeneratorUsingMonitor; -import com.baeldung.concurrent.mutex.SequenceGeneratorUsingReentrantLock; -import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSemaphore; -import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSynchronizedBlock; -import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSynchronizedMethod; - public class MutexUnitTest { - private final int RANGE = 30; - - @Test + // @Test + // This test verifies the race condition use case, it may pass or fail based on execution environment + // Uncomment @Test to run it public void givenUnsafeSequenceGenerator_whenRaceCondition_thenUnexpectedBehavior() throws Exception { - Set uniqueSequences = getASetOFUniqueSequences(new SequenceGenerator()); - Assert.assertNotEquals(RANGE, uniqueSequences.size()); + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGenerator(), count); + Assert.assertNotEquals(count, uniqueSequences.size()); } @Test public void givenSequenceGeneratorUsingSynchronizedMethod_whenRaceCondition_thenSuccess() throws Exception { - Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSynchronizedMethod()); - Assert.assertEquals(RANGE, uniqueSequences.size()); + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingSynchronizedMethod(), count); + Assert.assertEquals(count, uniqueSequences.size()); } @Test public void givenSequenceGeneratorUsingSynchronizedBlock_whenRaceCondition_thenSuccess() throws Exception { - Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSynchronizedBlock()); - Assert.assertEquals(RANGE, uniqueSequences.size()); + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingSynchronizedBlock(), count); + Assert.assertEquals(count, uniqueSequences.size()); } @Test public void givenSequenceGeneratorUsingReentrantLock_whenRaceCondition_thenSuccess() throws Exception { - Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingReentrantLock()); - Assert.assertEquals(RANGE, uniqueSequences.size()); + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingReentrantLock(), count); + Assert.assertEquals(count, uniqueSequences.size()); } @Test public void givenSequenceGeneratorUsingSemaphore_whenRaceCondition_thenSuccess() throws Exception { - Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSemaphore()); - Assert.assertEquals(RANGE, uniqueSequences.size()); + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingSemaphore(), count); + Assert.assertEquals(count, uniqueSequences.size()); } @Test public void givenSequenceGeneratorUsingMonitor_whenRaceCondition_thenSuccess() throws Exception { - Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingMonitor()); - Assert.assertEquals(RANGE, uniqueSequences.size()); + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingMonitor(), count); + Assert.assertEquals(count, uniqueSequences.size()); } - private Set getASetOFUniqueSequences(SequenceGenerator generator) throws Exception { + private Set getUniqueSequences(SequenceGenerator generator, int count) throws Exception { ExecutorService executor = Executors.newFixedThreadPool(3); - Set uniqueSequences = new HashSet<>(); + Set uniqueSequences = new LinkedHashSet<>(); List> futures = new ArrayList<>(); - for (int i = 0; i < RANGE; i++) { + for (int i = 0; i < count; i++) { futures.add(executor.submit(generator::getNextSequence)); } @@ -72,7 +71,7 @@ public class MutexUnitTest { uniqueSequences.add(future.get()); } - executor.awaitTermination(15, TimeUnit.SECONDS); + executor.awaitTermination(1, TimeUnit.SECONDS); executor.shutdown(); return uniqueSequences; diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/Employee.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/Employee.java new file mode 100644 index 0000000000..e43b6634ed --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/Employee.java @@ -0,0 +1,50 @@ +package com.baeldung.core.modifiers; + +public class Employee { + + private String privateId; + public String name; + private boolean manager; + + public Employee(String id, String name) { + changeId(id); + this.name = name; + } + + private Employee(String id, String name, boolean managerAttribute) { + this.privateId = id; + this.name = name; + this.privateId = id + "_ID-MANAGER"; + } + + public void changeId(String customId) { + if (customId.endsWith("_ID")) { + this.privateId = customId; + } else { + this.privateId = customId + "_ID"; + } + } + + public String getId() { + return privateId; + } + + public boolean isManager() { + return manager; + } + + public void elevateToManager() { + if ("Carl".equals(this.name)) { + setManager(true); + } + } + + private void setManager(boolean manager) { + this.manager = manager; + } + + public static Employee buildManager(String id, String name) { + return new Employee(id, name, true); + } + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/ExampleClass.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/ExampleClass.java new file mode 100644 index 0000000000..db58b4f00b --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/ExampleClass.java @@ -0,0 +1,10 @@ +package com.baeldung.core.modifiers; + +public class ExampleClass { + + public static void main(String[] args) { + Employee employee = new Employee("Bob","ABC123"); + employee.changeId("BCD234"); + System.out.println(employee.getId()); + } +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/PublicOuterClass.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/PublicOuterClass.java new file mode 100644 index 0000000000..329ebf3bb6 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/PublicOuterClass.java @@ -0,0 +1,16 @@ +package com.baeldung.core.modifiers; + +public class PublicOuterClass { + + public PrivateInnerClass getInnerClassInstance() { + PrivateInnerClass myPrivateClassInstance = this.new PrivateInnerClass(); + myPrivateClassInstance.id = "ID1"; + myPrivateClassInstance.name = "Bob"; + return myPrivateClassInstance; + } + + private class PrivateInnerClass { + public String name; + public String id; + } +}