1 静态内部类
1.1,先写简单的静态内部类,它自带同步的模式,可以放在多线程内使用。
public class StaticInnerClassSingleton {
private static class InnerClass{
private static StaticInnerClassSingleton staticInnerClassSingleton = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance(){
return InnerClass.staticInnerClassSingleton;
}
}
1.2,具体的实现方法
public class Test {
public static void main(String[] args) {
StaticInnerClassSingleton instance = StaticInnerClassSingleton.getInstance();
}
}
1.3 总结 ,这就是静态内部类实现的机制
2 饿汉类的实现
2.1 饿汉类的实现
public class HungrySingleton implements Serializable,Cloneable{
private final static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){
}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
2.2 具体的实现
public class Test {
public static void main(String[] args) {
HungrySingleton instance = HungrySingleton.getInstance();
}
}
2.3 总结,这就实现了饿汉类,饿汉顾名思义,就是它开始的时候很饿,需要吃的,而懒汉类,就是很懒,不到需要他不去做。
3,懒汉类的实现
3.1 主线程内的懒汉类,就是如果程序只是运行在主线程内,下面的懒汉类是可以正常使用的。
public class LazySingleton {
private static LazySingleton lazySingleton = null;
private LazySingleton(){
}
public static LazySingleton getInstance(){
if(lazySingleton == null){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
3.2 当程序处于子线程内的时候,该方法就需要增加线程锁
public class LazyDoubleCheckSingleton {
private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null;
private LazyDoubleCheckSingleton(){
}
public static LazyDoubleCheckSingleton getInstance(){
if(lazyDoubleCheckSingleton == null){
synchronized (LazyDoubleCheckSingleton.class){
if(lazyDoubleCheckSingleton == null){
lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton();
//1.分配内存给这个对象
// //3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址
//2.初始化对象
// intra-thread semantics
// ---------------//3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址
}
}
}
return lazyDoubleCheckSingleton;
}
}
注意看上面的代码,定义的时候,有个volatile 和synchronized ,这就是双重的校验锁的机制。
3.3 使用的方法
LazyDoubleCheckSingleton instance = LazyDoubleCheckSingleton.getInstance();
和上面的懒汉类的方式是一样的
4,实现子线程
4.1 科普一下如何做子线程,原来做子线程,都是放在类里面,现在感觉可以把该类单独拿出来
public class T implements Runnable {
@Override
public void run() {
// 具体的业务逻辑,比如新建一个类了,等方法
}
}
4.2 在main函数内进行调用
Thread t1 = new Thread(new T());
Thread t2 = new Thread(new T());
t1.start();
t2.start();