Skip to content

Commit 0474389

Browse files
alejandrogervasiojzheaux
authored andcommitted
What is thread-safety and how to achieve it
Issue: BAEL-2416
1 parent 65b9909 commit 0474389

21 files changed

Lines changed: 491 additions & 0 deletions
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.baeldung.concurrent.threadsafety.application;
2+
3+
import com.baeldung.concurrent.threadsafety.callables.AtomicCounterCallable;
4+
import com.baeldung.concurrent.threadsafety.mathutils.MathUtils;
5+
import com.baeldung.concurrent.threadsafety.callables.CounterCallable;
6+
import com.baeldung.concurrent.threadsafety.callables.ExtrinsicLockCounterCallable;
7+
import com.baeldung.concurrent.threadsafety.callables.MessageServiceCallable;
8+
import com.baeldung.concurrent.threadsafety.callables.ReentranReadWriteLockCounterCallable;
9+
import com.baeldung.concurrent.threadsafety.callables.ReentrantLockCounterCallable;
10+
import com.baeldung.concurrent.threadsafety.services.AtomicCounter;
11+
import com.baeldung.concurrent.threadsafety.services.Counter;
12+
import com.baeldung.concurrent.threadsafety.services.ExtrinsicLockCounter;
13+
import com.baeldung.concurrent.threadsafety.services.MessageService;
14+
import com.baeldung.concurrent.threadsafety.services.ReentrantLockCounter;
15+
import com.baeldung.concurrent.threadsafety.services.ReentrantReadWriteLockCounter;
16+
import java.util.ArrayList;
17+
import java.util.Arrays;
18+
import java.util.Collection;
19+
import java.util.Collections;
20+
import java.util.Map;
21+
import java.util.concurrent.ConcurrentHashMap;
22+
import java.util.concurrent.ExecutionException;
23+
import java.util.concurrent.ExecutorService;
24+
import java.util.concurrent.Executors;
25+
import java.util.concurrent.Future;
26+
27+
public class Application {
28+
29+
public static void main(String[] args) throws InterruptedException, ExecutionException {
30+
31+
new Thread(() -> {
32+
System.out.println(MathUtils.factorial(10));
33+
}).start();
34+
new Thread(() -> {
35+
System.out.println(MathUtils.factorial(5));
36+
}).start();
37+
38+
ExecutorService executorService = Executors.newFixedThreadPool(10);
39+
MessageService messageService = new MessageService("Welcome to Baeldung!");
40+
Future<String> future1 = (Future<String>) executorService.submit(new MessageServiceCallable(messageService));
41+
Future<String> future2 = (Future<String>) executorService.submit(new MessageServiceCallable(messageService));
42+
System.out.println(future1.get());
43+
System.out.println(future2.get());
44+
45+
Counter counter = new Counter();
46+
Future<Integer> future3 = (Future<Integer>) executorService.submit(new CounterCallable(counter));
47+
Future<Integer> future4 = (Future<Integer>) executorService.submit(new CounterCallable(counter));
48+
System.out.println(future3.get());
49+
System.out.println(future4.get());
50+
51+
ExtrinsicLockCounter extrinsicLockCounter = new ExtrinsicLockCounter();
52+
Future<Integer> future5 = (Future<Integer>) executorService.submit(new ExtrinsicLockCounterCallable(extrinsicLockCounter));
53+
Future<Integer> future6 = (Future<Integer>) executorService.submit(new ExtrinsicLockCounterCallable(extrinsicLockCounter));
54+
System.out.println(future5.get());
55+
System.out.println(future6.get());
56+
57+
ReentrantLockCounter reentrantLockCounter = new ReentrantLockCounter();
58+
Future<Integer> future7 = (Future<Integer>) executorService.submit(new ReentrantLockCounterCallable(reentrantLockCounter));
59+
Future<Integer> future8 = (Future<Integer>) executorService.submit(new ReentrantLockCounterCallable(reentrantLockCounter));
60+
System.out.println(future7.get());
61+
System.out.println(future8.get());
62+
63+
ReentrantReadWriteLockCounter reentrantReadWriteLockCounter = new ReentrantReadWriteLockCounter();
64+
Future<Integer> future9 = (Future<Integer>) executorService.submit(new ReentranReadWriteLockCounterCallable(reentrantReadWriteLockCounter));
65+
Future<Integer> future10 = (Future<Integer>) executorService.submit(new ReentranReadWriteLockCounterCallable(reentrantReadWriteLockCounter));
66+
System.out.println(future9.get());
67+
System.out.println(future10.get());
68+
69+
AtomicCounter atomicCounter = new AtomicCounter();
70+
Future<Integer> future11 = (Future<Integer>) executorService.submit(new AtomicCounterCallable(atomicCounter));
71+
Future<Integer> future12 = (Future<Integer>) executorService.submit(new AtomicCounterCallable(atomicCounter));
72+
System.out.println(future11.get());
73+
System.out.println(future12.get());
74+
75+
Collection<Integer> syncCollection = Collections.synchronizedCollection(new ArrayList<>());
76+
Thread thread11 = new Thread(() -> syncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6)));
77+
Thread thread12 = new Thread(() -> syncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6)));
78+
thread11.start();
79+
thread12.start();
80+
81+
Map<String,String> concurrentMap = new ConcurrentHashMap<>();
82+
concurrentMap.put("1", "one");
83+
concurrentMap.put("2", "two");
84+
concurrentMap.put("3", "three");
85+
}
86+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.concurrent.threadsafety.callables;
2+
3+
import com.baeldung.concurrent.threadsafety.services.AtomicCounter;
4+
import java.util.concurrent.Callable;
5+
6+
public class AtomicCounterCallable implements Callable<Integer> {
7+
8+
private final AtomicCounter counter;
9+
10+
public AtomicCounterCallable(AtomicCounter counter) {
11+
this.counter = counter;
12+
}
13+
14+
@Override
15+
public Integer call() throws Exception {
16+
counter.incrementCounter();
17+
return counter.getCounter();
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.concurrent.threadsafety.callables;
2+
3+
import com.baeldung.concurrent.threadsafety.services.Counter;
4+
import java.util.concurrent.Callable;
5+
6+
public class CounterCallable implements Callable<Integer> {
7+
8+
private final Counter counter;
9+
10+
public CounterCallable(Counter counter) {
11+
this.counter = counter;
12+
}
13+
14+
@Override
15+
public Integer call() throws Exception {
16+
counter.incrementCounter();
17+
return counter.getCounter();
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.concurrent.threadsafety.callables;
2+
3+
import com.baeldung.concurrent.threadsafety.services.ExtrinsicLockCounter;
4+
import java.util.concurrent.Callable;
5+
6+
public class ExtrinsicLockCounterCallable implements Callable<Integer> {
7+
8+
private final ExtrinsicLockCounter counter;
9+
10+
public ExtrinsicLockCounterCallable(ExtrinsicLockCounter counter) {
11+
this.counter = counter;
12+
}
13+
14+
@Override
15+
public Integer call() throws Exception {
16+
counter.incrementCounter();
17+
return counter.getCounter();
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.concurrent.threadsafety.callables;
2+
3+
import com.baeldung.concurrent.threadsafety.services.MessageService;
4+
import java.util.concurrent.Callable;
5+
6+
public class MessageServiceCallable implements Callable<String> {
7+
8+
private final MessageService messageService;
9+
10+
public MessageServiceCallable(MessageService messageService) {
11+
this.messageService = messageService;
12+
13+
}
14+
15+
@Override
16+
public String call() {
17+
return messageService.getMesssage();
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.baeldung.concurrent.threadsafety.callables;
2+
3+
import com.baeldung.concurrent.threadsafety.services.ReentrantReadWriteLockCounter;
4+
import java.util.concurrent.Callable;
5+
6+
public class ReentranReadWriteLockCounterCallable implements Callable<Integer> {
7+
8+
private final ReentrantReadWriteLockCounter counter;
9+
10+
public ReentranReadWriteLockCounterCallable(ReentrantReadWriteLockCounter counter) {
11+
this.counter = counter;
12+
}
13+
14+
@Override
15+
public Integer call() throws Exception {
16+
counter.incrementCounter();
17+
return counter.getCounter();
18+
}
19+
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.concurrent.threadsafety.callables;
2+
3+
import com.baeldung.concurrent.threadsafety.services.ReentrantLockCounter;
4+
import java.util.concurrent.Callable;
5+
6+
public class ReentrantLockCounterCallable implements Callable<Integer> {
7+
8+
private final ReentrantLockCounter counter;
9+
10+
public ReentrantLockCounterCallable(ReentrantLockCounter counter) {
11+
this.counter = counter;
12+
}
13+
14+
@Override
15+
public Integer call() throws Exception {
16+
counter.incrementCounter();
17+
return counter.getCounter();
18+
}
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.concurrent.threadsafety.mathutils;
2+
3+
import java.math.BigInteger;
4+
5+
public class MathUtils {
6+
7+
public static BigInteger factorial(int number) {
8+
BigInteger f = new BigInteger("1");
9+
for (int i = 2; i <= number; i++) {
10+
f = f.multiply(BigInteger.valueOf(i));
11+
}
12+
return f;
13+
}
14+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.baeldung.concurrent.threadsafety.services;
2+
3+
import java.util.concurrent.atomic.AtomicInteger;
4+
5+
public class AtomicCounter {
6+
7+
private final AtomicInteger counter = new AtomicInteger();
8+
9+
public AtomicCounter() {}
10+
11+
public void incrementCounter() {
12+
counter.incrementAndGet();
13+
}
14+
15+
public synchronized int getCounter() {
16+
return counter.get();
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.baeldung.concurrent.threadsafety.services;
2+
3+
public class Counter {
4+
5+
private volatile int counter;
6+
7+
public Counter() {
8+
this.counter = 0;
9+
}
10+
11+
public synchronized void incrementCounter() {
12+
counter += 1;
13+
}
14+
15+
public int getCounter() {
16+
return counter;
17+
}
18+
}

0 commit comments

Comments
 (0)