java多线程-单例模式(sing)的四种实现方式
单例模式保证了该类只会被实例化一次。在数据库链接,读取配置文件链接经常会使用到。下面来看看三种单例的实现。
1.懒汉模式,在使用时才会被实例化。
public class SignTest {
public static volatile SignTest signTest=null;
private SignTest(){}//保证了该类不能在被调用时被主动实例化。
public static SignTest SigntestInstall(){
if(signTest==null){
synchronized(SignTest.class){//双重加锁,防止高并发
if(signTest==null){//
signTest=new SignTest();
}
}
}
return signTest;
}
}
2.饥饿模式
““java
public class SingTest2 {
private static SingTest2 signTest=new SingTest2();
private SingTest2(){}//保证了该类不能在被调用时被主动实例化。
public static SingTest2 SigntestInstall(){
return signTest;
}
}
3.内部类实现
```java
public class SingTest3 {
private static class SingTestHelp{
private static SingTest3 singTest=new SingTest3();
}
private SingTest3(){}//保证了该类不能在被调用时被主动实例化。
public static SingTest3 SigntestInstall(){
return SingTestHelp.singTest;
}
}
<div class="se-preview-section-delimiter"></div>
4使用枚举
package cn.thread.first.syn;
class SigletonService {
private enum Sigleton {
connFaction;
private int i;
private Sigleton() {
i = 10;
}
public int getConn() {
return i;
}
}
public static int getConn() {
return Sigleton.connFaction.getConn();
}
}
public class EmunSigleton {
public static void main(String args[]) {
SigletonService.getConn();
}
}
<div class="se-preview-section-delimiter"></div>
解说2,3的实现方式:
饥饿模式与内部类看着有点差不多,很多人主推内部类,因为内部类在类初始化时不会被实例化
class SampleClass {
String s;
SampleClass(String s) {
this.s = s;
System.out.println(s);
}
SampleClass() {
System.out.println("6SampleClass默认构造函数被调用");
}
@Override
public String toString() {
return this.s;
}
}
public class ClassInitialDome {
static SampleClass sam = new SampleClass("1静态成员sam初始化");
SampleClass sam1 = new SampleClass("5普通成员sam1初始化");
static {
System.out.println("2static块执行");
if (sam == null)
System.out.println("sam is null");
sam = new SampleClass("3静态块内初始化sam成员变量");//3最后的结果会把1覆盖掉,它们是同一个对象的实例化
}
private static class SingDome {
private static ClassInitialDome classInitialDome = new ClassInitialDome();
}
public static ClassInitialDome getConn() {
return SingDome.classInitialDome;
}
private ClassInitialDome() {
System.out.println("7InitialOrderWithoutExtend默认构造函数被调用");
}
SampleClass sam2 = new SampleClass();//6,7,8是一样的级别,按代码顺序执行
public static void main(String[] args) {
System.out.println("第1个主类对象, 静态成员sam.s: " + sam);
System.out.println("第2个主类对象, 静态成员sam.s: " + sam);
}
}
<div class="se-preview-section-delimiter"></div>
输出结果:
1静态成员sam初始化
2static块执行
3静态块内初始化sam成员变量
可以看到1,2,3被打印出来了,而主类ClassInitialDome并没有开始实例化呢。
代码中添加一行:
private static ClassInitialDome classInitialDome = new ClassInitialDome();
日志中可以看到一行
输入中多了:7InitialOrderWithoutExtend默认构造函数被调用