这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.baeldung.threadsafe;

public class DoubleCheckedSingleton {
private static volatile DoubleCheckedSingleton instance;

private DoubleCheckedSingleton() {}

public static DoubleCheckedSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedSingleton();
}
}
}
return instance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.baeldung.threadsafe;

public class EagerSingleton {
private static final EagerSingleton INSTANCE = new EagerSingleton();

private EagerSingleton() {}

public static EagerSingleton getInstance() {
return INSTANCE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.baeldung.threadsafe;

public enum EnumSingleton {
INSTANCE;

public void performOperation() {
// Singleton operations here
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.baeldung.threadsafe;

public class SimpleSingleton {
private static SimpleSingleton instance;

private SimpleSingleton() {
}

public static SimpleSingleton getInstance() {
if (instance == null) {
instance = new SimpleSingleton();
}
return instance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.baeldung.threadsafe;

public class SynchronizedSingleton {
private static SynchronizedSingleton instance;

private SynchronizedSingleton() {}

public static synchronized SynchronizedSingleton getInstance() {
if (instance == null) {
instance = new SynchronizedSingleton();
}
return instance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.baeldung.threadsafe;

import com.baledung.billpugh.BillPughSingleton;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.concurrent.*;
import java.util.Set;
import java.util.HashSet;

public class BillPughSingletonUnitTest {
@Test
void testThreadSafety() throws InterruptedException {
int numberOfThreads = 10;
CountDownLatch latch = new CountDownLatch(numberOfThreads);
Set<BillPughSingleton> instances = ConcurrentHashMap.newKeySet();

for (int i = 0; i < numberOfThreads; i++) {
new Thread(() -> {
instances.add(BillPughSingleton.getInstance());
latch.countDown();
}).start();
}

latch.await(5, TimeUnit.SECONDS);

assertEquals(1, instances.size(), "All threads should get the same instance");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.baeldung.threadsafe;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.stream.IntStream;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class DoubleCheckedSingletonUnitTest {
@Test
void givenDCLSingleton_whenAccessedFromThreads_thenOneInstanceCreated() {
List<Object> instances = Collections.synchronizedList(new ArrayList<>());
IntStream.range(0, 100).parallel().forEach(i -> instances.add(DoubleCheckedSingleton.getInstance()));
assertEquals(1, new HashSet<>(instances).size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.baeldung.threadsafe;

import org.junit.jupiter.api.Test;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class EagerSingletonUnitTest {
@Test
void givenEagerSingleton_whenAccessedConcurrently_thenSingleInstanceCreated()
throws InterruptedException {

int threadCount = 1000;
Set<EagerSingleton> instances = ConcurrentHashMap.newKeySet();
CountDownLatch latch = new CountDownLatch(threadCount);

for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
instances.add(EagerSingleton.getInstance());
latch.countDown();
}).start();
}

latch.await();

assertEquals(1, instances.size(), "Only one instance should be created");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.baeldung.threadsafe;

import org.junit.jupiter.api.Test;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class EnumSingletonUnitTest {
@Test
void givenEnumSingleton_whenAccessedConcurrently_thenSingleInstanceCreated()
throws InterruptedException {

Set<EnumSingleton> instances = ConcurrentHashMap.newKeySet();
CountDownLatch latch = new CountDownLatch(100);

for (int i = 0; i < 100; i++) {
new Thread(() -> {
instances.add(EnumSingleton.INSTANCE);
latch.countDown();
}).start();
}

latch.await();
assertEquals(1, instances.size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.baeldung.threadsafe;

import org.junit.jupiter.api.Test;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

import static org.junit.jupiter.api.Assertions.assertTrue;

public class SimpleSingletonUnitTest {
@Test
void givenUnsafeSingleton_whenAccessedConcurrently_thenMultipleInstancesCreated() throws InterruptedException {
int threadCount = 1000;
Set<SimpleSingleton> instances = ConcurrentHashMap.newKeySet();
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
instances.add(SimpleSingleton.getInstance());
latch.countDown();
}).start();
}
latch.await();
assertTrue(instances.size() > 1, "Multiple instances were created");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.baeldung.threadsafe;

import org.junit.jupiter.api.Test;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.IntStream;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class SynchronizedSingletonUnitTest {
@Test
void givenMultipleThreads_whenUsingSynchronizedSingleton_thenOnlyOneInstanceCreated() {
Set<Object> instances = ConcurrentHashMap.newKeySet();
IntStream.range(0, 100).parallel().forEach(i -> instances.add(SynchronizedSingleton.getInstance()));
assertEquals(1, instances.size());
}
}