出于方便,引用了之前单例模式(懒汉模式)的源码进行的改进,做于个人笔记记录
在此处解释同步块和同步方法的区别
同步块是在方法里面将一段代码加上同步锁
而同步方法是将整个方法加上同步锁
非静态同步方法和同步块一样
静态方法和非静态方法最主要的区别还是对象的问题,静态方法所在的类无论有多少个对象,同一时间还是只能有一个线程执行同步静态方法
只要有多个对象,还是可以有多个线程同时执行非静态方法
/**
* 单例设计模式
* 确保一个类只有一个对象
* @author Administrator
*
*/
public class SingletonPattern {
public static void main(String[] args) {
ThreadTest test01 = new ThreadTest(100);
ThreadTest test02 = new ThreadTest(1000);
test01.start();
test02.start();
}
}
class ThreadTest extends Thread{//模拟多线程
private long time;
public ThreadTest() {
}
public ThreadTest(long time) {
this.time = time;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"创建对象:"+Test.getInstance(time));
}
}
/*
* 单例设计模式
* 懒汉式 不创建对象,在使用时再创建对象 double checking 双重检查
* 1.构造器私有化 避免外部直接创建对象
* 2.声明一个私有静态变量
* 3.创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
*/
class Test{
//声明一个私有静态变量
private static Test testInstance = null;
//构造器私有化 避免外部直接创建对象
private Test(){
}
//创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
public static synchronized Test getInstance02(long time){//如果没有加入synchronized同步的话 ,创建对象的地址就会发生改变,导致创建的对象不是只有一个对象,但是非静态方法锁住的是对象中的方法
if(null == testInstance){
try {
Thread.sleep(time);//加入延时,放大发生错误的概率,一般不会添加long time
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
testInstance = new Test();
}
return testInstance;
}
public static Test getInstance(long time){//如果没有加入synchronized同步的话 ,创建对象的地址就会发生改变,导致创建的对象不是只有一个对象
if(null == testInstance)
synchronized (Test.class) {//锁定字节码信息
if(null == testInstance){
try {
Thread.sleep(time);//加入延时,放大发生错误的概率,一般不会添加long time
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
testInstance = new Test();
}
}
return testInstance;
}
public static Test getInstance3(long time){//如果没有加入synchronized同步的话 ,创建对象的地址就会发生改变,导致创建的对象不是只有一个对象
synchronized (Test.class) {//锁定字节码信息
if(null == testInstance){
try {
Thread.sleep(time);//加入延时,放大发生错误的概率,一般不会添加long time
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
testInstance = new Test();
}
return testInstance;
}
}
}