Skip to content

Commit 4562a2f

Browse files
kamleshkrmaibin
authored andcommitted
Code example: Using a Mutex Object in Java (eugenp#7587)
1 parent b3547bc commit 4562a2f

7 files changed

Lines changed: 168 additions & 0 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.baeldung.concurrent.mutex;
2+
3+
public class SequenceGenerator {
4+
private int currentValue = 0;
5+
6+
public int getNextSequence() throws InterruptedException {
7+
currentValue = currentValue + 1;
8+
Thread.sleep(500);
9+
return currentValue;
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.baeldung.concurrent.mutex;
2+
3+
import com.google.common.util.concurrent.Monitor;
4+
5+
public class SequenceGeneratorUsingMonitor extends SequenceGenerator {
6+
7+
private Monitor monitor = new Monitor();
8+
9+
@Override
10+
public int getNextSequence() throws InterruptedException {
11+
monitor.enter();
12+
try {
13+
return super.getNextSequence();
14+
} finally {
15+
monitor.leave();
16+
}
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.baeldung.concurrent.mutex;
2+
3+
import java.util.concurrent.locks.ReentrantLock;
4+
5+
public class SequenceGeneratorUsingReentrantLock extends SequenceGenerator {
6+
7+
private ReentrantLock mutex = new ReentrantLock();
8+
9+
@Override
10+
public int getNextSequence() throws InterruptedException {
11+
try {
12+
mutex.lock();
13+
return super.getNextSequence();
14+
} finally {
15+
mutex.unlock();
16+
}
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.baeldung.concurrent.mutex;
2+
3+
import java.util.concurrent.Semaphore;
4+
5+
public class SequenceGeneratorUsingSemaphore extends SequenceGenerator {
6+
7+
private Semaphore mutex = new Semaphore(1);
8+
9+
@Override
10+
public int getNextSequence() throws InterruptedException {
11+
try {
12+
mutex.acquire();
13+
return super.getNextSequence();
14+
} finally {
15+
mutex.release();
16+
}
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.baeldung.concurrent.mutex;
2+
3+
public class SequenceGeneratorUsingSynchronizedBlock extends SequenceGenerator {
4+
5+
@Override
6+
public int getNextSequence() throws InterruptedException {
7+
synchronized (this) {
8+
return super.getNextSequence();
9+
}
10+
}
11+
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.baeldung.concurrent.mutex;
2+
3+
public class SequenceGeneratorUsingSynchronizedMethod extends SequenceGenerator {
4+
5+
@Override
6+
public synchronized int getNextSequence() throws InterruptedException {
7+
return super.getNextSequence();
8+
}
9+
10+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.baeldung.concurrent.mutex;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashSet;
5+
import java.util.List;
6+
import java.util.Set;
7+
import java.util.concurrent.ExecutorService;
8+
import java.util.concurrent.Executors;
9+
import java.util.concurrent.Future;
10+
import java.util.concurrent.TimeUnit;
11+
12+
import org.junit.Assert;
13+
import org.junit.Test;
14+
15+
import com.baeldung.concurrent.mutex.SequenceGenerator;
16+
import com.baeldung.concurrent.mutex.SequenceGeneratorUsingMonitor;
17+
import com.baeldung.concurrent.mutex.SequenceGeneratorUsingReentrantLock;
18+
import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSemaphore;
19+
import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSynchronizedBlock;
20+
import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSynchronizedMethod;
21+
22+
public class MutexUnitTest {
23+
24+
private final int RANGE = 30;
25+
26+
@Test
27+
public void givenUnsafeSequenceGenerator_whenRaceCondition_thenUnexpectedBehavior() throws Exception {
28+
Set<Integer> uniqueSequences = getASetOFUniqueSequences(new SequenceGenerator());
29+
Assert.assertNotEquals(RANGE, uniqueSequences.size());
30+
}
31+
32+
@Test
33+
public void givenSequenceGeneratorUsingSynchronizedMethod_whenRaceCondition_thenSuccess() throws Exception {
34+
Set<Integer> uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSynchronizedMethod());
35+
Assert.assertEquals(RANGE, uniqueSequences.size());
36+
}
37+
38+
@Test
39+
public void givenSequenceGeneratorUsingSynchronizedBlock_whenRaceCondition_thenSuccess() throws Exception {
40+
Set<Integer> uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSynchronizedBlock());
41+
Assert.assertEquals(RANGE, uniqueSequences.size());
42+
}
43+
44+
@Test
45+
public void givenSequenceGeneratorUsingReentrantLock_whenRaceCondition_thenSuccess() throws Exception {
46+
Set<Integer> uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingReentrantLock());
47+
Assert.assertEquals(RANGE, uniqueSequences.size());
48+
}
49+
50+
@Test
51+
public void givenSequenceGeneratorUsingSemaphore_whenRaceCondition_thenSuccess() throws Exception {
52+
Set<Integer> uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSemaphore());
53+
Assert.assertEquals(RANGE, uniqueSequences.size());
54+
}
55+
56+
@Test
57+
public void givenSequenceGeneratorUsingMonitor_whenRaceCondition_thenSuccess() throws Exception {
58+
Set<Integer> uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingMonitor());
59+
Assert.assertEquals(RANGE, uniqueSequences.size());
60+
}
61+
62+
private Set<Integer> getASetOFUniqueSequences(SequenceGenerator generator) throws Exception {
63+
ExecutorService executor = Executors.newFixedThreadPool(3);
64+
Set<Integer> uniqueSequences = new HashSet<>();
65+
List<Future<Integer>> futures = new ArrayList<>();
66+
67+
for (int i = 0; i < RANGE; i++) {
68+
futures.add(executor.submit(generator::getNextSequence));
69+
}
70+
71+
for (Future<Integer> future : futures) {
72+
uniqueSequences.add(future.get());
73+
}
74+
75+
executor.awaitTermination(15, TimeUnit.SECONDS);
76+
executor.shutdown();
77+
78+
return uniqueSequences;
79+
}
80+
81+
}

0 commit comments

Comments
 (0)