单例设计模式--->确保一个类只有一个对象
懒汉式单例模式
- 构造器私有化,避免外部直接创建对象
- 声明一个私有的静态变量
- 创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
package TreadLearning;
import org.omg.CORBA.SystemException;
/**
* 单列设计模式:确保一个类只有一个对象
*
* @author 袁盛桐
*
*/
public class synsingle {
public static void main(String[] args) {
//创建两个线程,启动后由于jvm中的getinstance方法是synchronized
//所以第一个线程进去后先创建一个实例,执行结束后
//第二个线程才可以进入方法,由于第一个线程已经创建实例,所以直接返回,故是同一对象
jvmthread demo1 = new jvmthread();
jvmthread demo2 = new jvmthread();
demo1.start();
demo2.start();
}
}
class jvmthread extends Thread{
public jvmthread() {
// TODO Auto-generated constructor stub
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->create"+jvm.getInstance());
}
}
/**
* 单利设计模式
* 确保一个类只有一个对象
* 懒汉式
* 1.构造器私有化,避免外部直接创建对象
* 2.声明一个私有的静态变量
* 3.创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
*/
class jvm{
//声明一个私有的静态变量
private static jvm instance = null;
//构造器私有化,避免外部直接创建对象
private jvm() {
}
//创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
public static synchronized jvm getInstance() {
if(null == instance) {
instance = new jvm();
}
return instance;
}
}
由于创建两个线程,启动后由于jvm中的getinstance方法是synchronized,所以第一个线程进去后先创建一个实例,执行结束后第二个线程才可以进入方法,由于第一个线程已经创建实力,所以直接返回,故是同一对象
上述线程安全采用的式同步方法,下面采用同步代码块 并且采用3层检查double check方式
double check详解--->提高效率
//创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
public static jvm getInstance() {
//在外面再加一层判断为了提高效率,如果存在实例直接返回
if(null == instance) {
//对jvm上锁,利用jvm的字节码,相当于类模板锁住,不能再继续创建新的类实例了
synchronized(jvm.class) {
if(null == instance) {
instance = new jvm();
}
}
}
return instance;
}
假设有thread a 和 thread b 和 thread c
- a 和 b 同时创建,进入第一层if判断,结果instance为空,都进入第二层
- 在第二层由于对jvm.class是synchronized,所以a 先进入第二层,b等候
- a进入第二层后发现instace为空,创建instance然后返回
- b进入第二层发现instance不为空,直接跳出第三层if判断,返回instance
- 这时候c创建,在第一层时候直接判断instance不为空,直接返回instance,节约了时间