懒汉单例、synchronized确保线程安全测试实例
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package top.fjy8018.designpattern.pattern.creational.singleton;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 懒汉式单例:延迟加载(线程安全)
|
||||
*
|
||||
* @author F嘉阳
|
||||
* @date 2018-09-24 10:29
|
||||
*/
|
||||
@Slf4j
|
||||
public class LazySingletonSynchronized {
|
||||
private static LazySingletonSynchronized lazySingleton = null;
|
||||
|
||||
/**
|
||||
* 单例模式构造器必须是屏蔽的
|
||||
*/
|
||||
private LazySingletonSynchronized() {
|
||||
}
|
||||
|
||||
/**
|
||||
* synchronized确保线程安全
|
||||
* synchronized用于静态方法是对class文件加锁,用于普通方法则是对堆内存中的实例方法加锁
|
||||
* synchronized(LazySingletonSynchronized.class)与在方法名上加锁效果一致
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static LazySingletonSynchronized getInstance() {
|
||||
synchronized (LazySingletonSynchronized.class) {
|
||||
if (lazySingleton == null) {
|
||||
log.debug("LazySingletonSynchronized实例化");
|
||||
lazySingleton = new LazySingletonSynchronized();
|
||||
}
|
||||
}
|
||||
return lazySingleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* 线程安全验证
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public synchronized static LazySingletonSynchronized getInstance2() throws InterruptedException {
|
||||
if (lazySingleton == null) {
|
||||
// 使用线程等待模拟复杂实例化过程,让多线程同时进入该方法
|
||||
Thread.sleep(1000);
|
||||
log.debug("LazySingletonSynchronized实例化");
|
||||
lazySingleton = new LazySingletonSynchronized();
|
||||
}
|
||||
return lazySingleton;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package top.fjy8018.designpattern.pattern.creational.singleton;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author F嘉阳
|
||||
* @date 2018-09-24 10:53
|
||||
*/
|
||||
@Slf4j
|
||||
public class MyRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
LazySingleton lazySingleton = null;
|
||||
try {
|
||||
lazySingleton = LazySingleton.getInstance2();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
log.info(Thread.currentThread().getName() + " " + lazySingleton);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package top.fjy8018.designpattern.pattern.creational.singleton;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Slf4j
|
||||
class LazySingletonSynchronizedTest {
|
||||
|
||||
@Test
|
||||
void getInstance() {
|
||||
LazySingletonSynchronized.getInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getInstance2() throws InterruptedException {
|
||||
Thread thread1 = new Thread(new LazySingletonSynchronizedTest.MyRunnable());
|
||||
Thread thread2 = new Thread(new LazySingletonSynchronizedTest.MyRunnable());
|
||||
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
|
||||
Thread.sleep(3000);
|
||||
log.debug("finish");
|
||||
}
|
||||
|
||||
private class MyRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
LazySingletonSynchronized lazySingleton = null;
|
||||
try {
|
||||
lazySingleton = LazySingletonSynchronized.getInstance2();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
log.info(Thread.currentThread().getName() + " " + lazySingleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,4 +31,17 @@ class LazySingletonTest {
|
||||
log.debug("finish");
|
||||
|
||||
}
|
||||
|
||||
private class MyRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
LazySingleton lazySingleton = null;
|
||||
try {
|
||||
lazySingleton = LazySingleton.getInstance2();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
log.info(Thread.currentThread().getName() + " " + lazySingleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user