单例,包括懒汉式线程安全

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/myloveprogrmming/article/details/83713813
package danli;

public class Test1 {

	public static void main(String[] args) {
		SingleTest s=new SingleTest();
		Thread t1=new Thread(s);
		Thread t2=new Thread(s);
		t1.start();
		t2.start();

	}

}

class SingleInstance
{
	private SingleInstance() {}
	private static SingleInstance single=null;
	public static SingleInstance getInstance()
	{
		if(single==null)
		{
			synchronized(SingleInstance.class) {
				if(single==null)
				{
					single=new SingleInstance();
				}
			}
		}
		return single;
	}
}
class SingleTest implements Runnable
{
	public void run() {
		for(int i=0;i<=20;i++) {
		System.out.println(Thread.currentThread().getName()+"  "+SingleInstance.getInstance());
		}
	}
	
}

输出:

Thread-1  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-0  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
Thread-1  danli.SingleInstance@2f1eeb2f
 

普通的懒汉式单例:

package day12;
/*
 * 设计模式:将前人总结好的经验我们直接拿来使用.
 * 一共有23种,常用的有单例设计模式,模板设计模式,工厂设计模式,装饰设计模式,适配器设计模式,代理设计模式.
 * 
 * 单例设计模式:一个类只允许有一个对象,建立一个全局的访问点,将他提供出去供大家使用.
 * 分析:
 * 1.用户只允许有一个对象
 * 2.单例类
 * 3.全局的访问点:得到的唯一的对象就是全局的访问点,怎么做到全局?---static
 * 4.提供出去?
 * 5.供大家使用?---单例的功能,通过给单例类添加成员实现
 * 
 * 单例类的作用:1.可以实现两个对象之间的传值
 * 2.可以在全局范围内调用很多的功能.
 * 好处:可以让两个对象在完全没有关系的前提下,实现值的传递,降低了耦合性,提高了内聚性
 * 
 * 耦合性,内聚性在微观上说:描述的是类与类之间的关系
 * 好处:我们应该尽量提高内聚性,减少耦合性,可以提高程序的健壮性,增加代码的可移植性,方便实现模块儿化编程
 * 
 * 如何做到低耦合高内聚?
 * 在处理类与类关系的时候,让类之间的关系越紧密耦合性越高,内聚性越低.反之,关系越松散耦合性越低,内聚性越高.
 */

//单例类
//饿汉式:在定义变量的同时完成赋值
class SingleInstance{
	//第二步:在单例类的内部创建当前类的对象,私有化并变成静态的
	private static SingleInstance singleInstance = new SingleInstance();

	//第一步:将构造方法私有化
	private SingleInstance() {
		
	}
	//第三步:建立一个静态的公共的方法,将单例类对象提供出去
	public static SingleInstance getInstance() {
		return singleInstance;
	}
	
	//功能区---一般创建的是非静态的成员实现功能
	//创建成员变量
	//创建成员方法
}

//单例类
//懒汉式:开始只是定义变量,什么时候使用,什么时候赋值
class SingleInstance1{
	//第二步:在单例类的内部创建当前类的对象,私有化并变成静态的
	private static SingleInstance1 singleInstance = null;

	//第一步:将构造方法私有化
	private SingleInstance1() {
		
	}
	//第三步:建立一个静态的公共的方法,将单例类对象提供出去
	public static SingleInstance1 getInstance() {
		if (singleInstance == null) {//为了保证对象的唯一性
			singleInstance = new SingleInstance1();
			//为什么静态方法可以调用非静态的构造函数?
			//1构造函数不能被static修饰
			//2 构造函数的调不需要实例
		}
		
		return singleInstance;
	}
	
	//功能区---一般创建的是非静态的成员实现功能
	//创建成员变量
	//创建成员方法
	int num;
}

//实例:有两个类A,B.要求将A中的值传到B类中
class A1{
	int num1;
	
	//通过单例传值
	public void danLiTest1(){
		SingleInstance1 singleInstance1 = SingleInstance1.getInstance();
		singleInstance1.num = num1;
	}
}

class B1{
	int num2;
	//通过传参实现传值
	public void chanCanTest(A1 a){
		num2 = a.num1;
	}
	
	//通过单例传值
	public void danLiTest2(){
		SingleInstance1 singleInstance1 = SingleInstance1.getInstance();
		num2 = singleInstance1.num;
	}
}
public class Demo6 {
	public static void main(String[] args) {
//		SingleInstance singleInstance1 = new SingleInstance();
//		SingleInstance singleInstance2 = new SingleInstance();
//		System.out.println(singleInstance1 == singleInstance2);// false
		
		//使用单例
		SingleInstance singleInstance1 =  SingleInstance.getInstance();
		SingleInstance singleInstance2 =  SingleInstance.getInstance();
		System.out.println(singleInstance1 == singleInstance2);//true
		
		//要求将A中的值传到B类中
		A1 a = new A1();
		B1 b = new B1();
		
		a.num1 = 4;
		
		//传值第一种方法:直接传值
		//不可取,一般成员变量都是私有的
		b.num2 = a.num1;
		
		//第二种方式:传参,让A类与B类之间产生了关系.
		b.chanCanTest(a);
		
		//第三种方式:通过单例传值,让A类与B类之间是独立的
		a.danLiTest1();
		b.danLiTest2();
	}
}

猜你喜欢

转载自blog.csdn.net/myloveprogrmming/article/details/83713813