7 changed files with 413 additions and 0 deletions
@ -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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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