7 changed files with 413 additions and 0 deletions
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
/* |
||||
* Copyright (C) 2023 niushuai233 niushuai.cc |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package cc.niushuai.demo.designpattern.creatormodel.singleton; |
||||
|
||||
import cn.hutool.core.thread.ThreadUtil; |
||||
|
||||
import java.util.concurrent.atomic.AtomicReference; |
||||
|
||||
/** |
||||
* TODO |
||||
* |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:49 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public class CASSingleton { |
||||
|
||||
private static final AtomicReference<CASSingleton> INSTANCE = new AtomicReference<>(); |
||||
|
||||
private CASSingleton() { |
||||
ThreadUtil.sleep(3000); |
||||
System.out.println(Thread.currentThread().getName() + " -> " + getClass().getName() + " has been initialized"); |
||||
} |
||||
|
||||
public static CASSingleton getInstance() { |
||||
|
||||
CASSingleton casSingleton = INSTANCE.get(); |
||||
if (casSingleton != null) { |
||||
return casSingleton; |
||||
} |
||||
INSTANCE.compareAndSet(null, new CASSingleton()); |
||||
|
||||
return INSTANCE.get(); |
||||
} |
||||
|
||||
public static CASSingleton getInstance_forEach() { |
||||
|
||||
while (true) { |
||||
CASSingleton casSingleton = INSTANCE.get(); |
||||
if (casSingleton != null) { |
||||
return casSingleton; |
||||
} |
||||
if (INSTANCE.compareAndSet(null, new CASSingleton())) { |
||||
return INSTANCE.get(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void hello(String world) { |
||||
System.out.println("hello " + world); |
||||
} |
||||
} |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
/* |
||||
* Copyright (C) 2023 niushuai233 niushuai.cc |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package cc.niushuai.demo.designpattern.creatormodel.singleton; |
||||
|
||||
/** |
||||
* 枚举单例模式 |
||||
* |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 14:00 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public enum EnumSingleton { |
||||
|
||||
INSTANCE; |
||||
|
||||
public void hello(String item) { |
||||
System.out.println("Hello " + item); |
||||
} |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
/* |
||||
* Copyright (C) 2023 niushuai233 niushuai.cc |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package cc.niushuai.demo.designpattern.creatormodel.singleton; |
||||
|
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
/** |
||||
* 简单单例模式 |
||||
* |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:17 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public class Singleton { |
||||
|
||||
public static final Map<String, Object> map = new ConcurrentHashMap<>(); |
||||
|
||||
private Singleton() { |
||||
System.out.println(Thread.currentThread().getName() + " -> " + getClass().getName() + " has been initialized"); |
||||
} |
||||
|
||||
/** |
||||
* 简单单例模式 |
||||
* |
||||
* @return |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:18 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public static Map<String, Object> getMap() { |
||||
return map; |
||||
} |
||||
} |
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
/* |
||||
* Copyright (C) 2023 niushuai233 niushuai.cc |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package cc.niushuai.demo.designpattern.creatormodel.singleton.lazy; |
||||
|
||||
import cn.hutool.core.date.DateUtil; |
||||
|
||||
/** |
||||
* 懒汉模式 |
||||
* |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:14 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public class LazySingleton { |
||||
|
||||
private static LazySingleton INSTANCE; |
||||
|
||||
private LazySingleton() { |
||||
System.out.println(Thread.currentThread().getName() + " -> " + getClass().getName() + " has been initialized"); |
||||
} |
||||
|
||||
/** |
||||
* 获取LazySingleton 线程不安全 存在同时获取多个实例时new了多个instance到内存中 |
||||
* |
||||
* @return |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:15 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public static LazySingleton getInstance_threadUnsafe() { |
||||
if (null == INSTANCE) { |
||||
INSTANCE = new LazySingleton(); |
||||
} |
||||
return INSTANCE; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 获取LazySingleton 线程安全 |
||||
* |
||||
* @return |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:16 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public static synchronized LazySingleton getInstance_threadSafe() { |
||||
if (null == INSTANCE) { |
||||
INSTANCE = new LazySingleton(); |
||||
} |
||||
return INSTANCE; |
||||
} |
||||
|
||||
public void hello(String str) { |
||||
System.out.println(Thread.currentThread().getName() + ": hello " + str + " ==>" + DateUtil.now()); |
||||
} |
||||
} |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
/* |
||||
* Copyright (C) 2023 niushuai233 niushuai.cc |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package cc.niushuai.demo.designpattern.creatormodel.singleton.lazy; |
||||
|
||||
import cn.hutool.core.date.DateUtil; |
||||
|
||||
/** |
||||
* 使用内部类的方式进行懒加载 自身线程安全 不需要锁来管控线程安全 |
||||
* |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:21 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public class LazySingletonInnerClass { |
||||
|
||||
public static LazySingletonInnerClass INSTANCE = new LazySingletonInnerClass(); |
||||
|
||||
private LazySingletonInnerClass() { |
||||
System.out.println(Thread.currentThread().getName() + " -> " + getClass().getName() + " has been initialized"); |
||||
} |
||||
|
||||
public static void say() { |
||||
INSTANCE.hello("say"); |
||||
} |
||||
|
||||
/** |
||||
* 自身线程安全 不需要锁 只有加载内部类时单例才会被实例化 |
||||
* |
||||
* @return |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:23 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public static LazySingletonInnerClass getInstance() { |
||||
return LazySingletonInnerClassHolder.INSTANCE; |
||||
} |
||||
|
||||
public void hello(String str) { |
||||
System.out.println(Thread.currentThread().getName() + ": hello " + str + " ==>" + DateUtil.now()); |
||||
} |
||||
|
||||
public static class LazySingletonInnerClassHolder { |
||||
|
||||
private LazySingletonInnerClassHolder() { |
||||
System.out.println(Thread.currentThread().getName() + " -> " + getClass().getName() + " has been initialized"); |
||||
} |
||||
|
||||
public static final LazySingletonInnerClass INSTANCE = new LazySingletonInnerClass(); |
||||
} |
||||
} |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
/* |
||||
* Copyright (C) 2023 niushuai233 niushuai.cc |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
/** |
||||
* 单例模式 |
||||
* |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 11:09 |
||||
* @since 0.0.1 |
||||
*/ |
||||
package cc.niushuai.demo.designpattern.creatormodel.singleton; |
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
/* |
||||
* Copyright (C) 2023 niushuai233 niushuai.cc |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package cc.niushuai.demo.designpattern.creatormodel.singleton; |
||||
|
||||
import cc.niushuai.demo.designpattern.creatormodel.singleton.lazy.LazySingleton; |
||||
import cc.niushuai.demo.designpattern.creatormodel.singleton.lazy.LazySingletonInnerClass; |
||||
import cn.hutool.core.date.DateUtil; |
||||
import cn.hutool.core.thread.ThreadUtil; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import java.util.List; |
||||
import java.util.concurrent.ForkJoinPool; |
||||
|
||||
/** |
||||
* 单例模式 test |
||||
* |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 14:05 |
||||
* @since 0.0.1 |
||||
*/ |
||||
public class SingletonTest { |
||||
|
||||
@Test |
||||
public void testSingleton() { |
||||
Singleton.map.put("date", DateUtil.now()); |
||||
System.out.println(Singleton.map.get("date")); |
||||
} |
||||
|
||||
|
||||
@Test |
||||
public void testSingleton_lazy_unsafe() { |
||||
|
||||
List<String> strings = List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); |
||||
|
||||
new ForkJoinPool().submit(() -> strings.parallelStream().forEach(item -> LazySingleton.getInstance_threadUnsafe().hello(item))); |
||||
ThreadUtil.sleep(3000); |
||||
System.out.println("testSingleton_lazy_unsafe end"); |
||||
} |
||||
|
||||
@Test |
||||
public void testSingleton_lazy_safe() { |
||||
|
||||
List<String> strings = List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); |
||||
|
||||
new ForkJoinPool().submit(() -> strings.parallelStream().forEach(item -> LazySingleton.getInstance_threadSafe().hello(item))); |
||||
ThreadUtil.sleep(3000); |
||||
System.out.println("testSingleton_lazy_unsafe end"); |
||||
} |
||||
|
||||
@Test |
||||
public void testSingletonInnerClass() { |
||||
|
||||
LazySingletonInnerClass.say(); |
||||
System.out.println("============================================================================================"); |
||||
|
||||
List<String> strings = List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); |
||||
new ForkJoinPool().submit(() -> strings.parallelStream().forEach(item -> LazySingletonInnerClass.getInstance().hello(item))); |
||||
|
||||
ThreadUtil.sleep(3000); |
||||
System.out.println("testSingletonInnerClass end"); |
||||
} |
||||
|
||||
/** |
||||
* 仍然有可能创建出多个对象,但是INSTANCE一旦被赋予 则不再被改变 其他已创建的对象可认同为无用对象 并且等待被GC回收 |
||||
* |
||||
* @return |
||||
* @author niushuai233 |
||||
* @date 2024/1/5 14:54 |
||||
* @since 0.0.1 |
||||
*/ |
||||
@Test |
||||
public void testCASSingleton() { |
||||
|
||||
List<String> strings = List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); |
||||
new ForkJoinPool().submit(() -> strings.parallelStream().forEach(item -> CASSingleton.getInstance().hello(item))); |
||||
|
||||
CASSingleton.getInstance().hello("world"); |
||||
|
||||
ThreadUtil.sleep(3000); |
||||
System.out.println("testSingletonInnerClass end"); |
||||
} |
||||
|
||||
@Test |
||||
public void testEnumSingleton() { |
||||
|
||||
List<String> strings = List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); |
||||
new ForkJoinPool().submit(() -> strings.parallelStream().forEach(item -> EnumSingleton.INSTANCE.hello(item))); |
||||
|
||||
EnumSingleton.INSTANCE.hello("world"); |
||||
|
||||
ThreadUtil.sleep(3000); |
||||
System.out.println("testEnumSingleton end"); |
||||
} |
||||
} |
Loading…
Reference in new issue