看代码
/**
* 单利模式分设计3要素:
* 1、构造函数私有化,使其不能在外部使用new关键字实例化对象
* 2、在该类内部产生一个唯一实例化对象,并且将其封装成private static类型
* 3、定义一个静态方法返回该唯一对象
* 单例模式包含两种:饿汉式和懒汉式
* 饿汉式:使用类的时候已经将对象创建完毕,通常的做法就是在定义的时候实例化对象
* 优点:实现简单,不存在线程同步问题;
* 缺点:占用内存
* @author Lenovo
*
*/
public class Singleton {
//将对象设置为一个属性,并且用private static修饰,产生一个唯一属性
private static final Singleton instance = new Singleton(); //饿汉式
// 构造方法私有化
private Singleton(){
System.out.println("****Singletong Constructor*******");
}
//静态方法返回创建的对象
public static Singleton getInstance(){
return instance;
}
public void print(){
System.out.println("*****单利类******");
}
}
测试结果:
一、单线程:
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
singleton.print();
}
print:
*****单利类******
二、多线程:
public class DemoMain {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
public void run() {
Singleton.getInstance().print();
}
}, "线程" + i).start();
}
}
}
print:
****Singletong Constructor*******
*****单利类******
*****单利类******
*****单利类******
以上测试可见:Singleton的构造函数只执行了一次,说明不存在线程不同步的问题。
第二类:懒汉式:
/**
* 懒汉式:在使用的时候再创建实例化对象,懒,顾名思义就是不提前做准备,用的时候再创建。
* 优点:特定情况下节约内存;
* 缺点:存在线程不同步问题,不能实现对象的唯一性。
* @author Lenovo
*
*/
public class Singleton {
//将对象设置为一个属性,并且用private static修饰,产生一个唯一属性
private static Singleton instance = null; //懒汉式
// 构造方法私有化
private Singleton(){
System.out.println("****Singletong Constructor*******");
}
//静态方法返回创建的对象
public static Singleton getInstance(){
if (null == instance){
instance = new Singleton();
}
return instance;
}
public void print(){
System.out.println("*****"+ Thread.currentThread().getName() +"单利类******");
}
}
多线程测试(测试代码不变):
****Singletong Constructor*******
****Singletong Constructor*******
*****线程2单利类******
****Singletong Constructor*******
*****线程0单利类******
*****线程1单利类******
从上面的结果看出,Singleton的构造函数执行力3次,说明实例化了3个对象,出现了不同步问题。
为了解决不同步问题,可以在getInstance函数增加synchronized关键字,即:
//静态方法返回创建的对象
public static synchronized Singleton getInstance(){
if (null == instance){
instance = new Singleton();
}
return instance;
}
synchronized关键字虽然解决了线程,却引入了效率问题,通常的解决方式式在实例化的程序块增加synchronized关键字,即:
/**
* 懒汉式:在使用的时候再创建实例化对象,懒,顾名思义就是不提前做准备,用的时候再创建。
* 优点:特定情况下节约内存;
* 缺点:存在线程不同步问题,不能实现对象的唯一性。
* @author Lenovo
*
*/
public class Singleton {
//将对象设置为一个属性,并且用private static修饰,产生一个唯一属性
private static Singleton instance = null; //懒汉式
// 构造方法私有化
private Singleton(){
System.out.println("****Singletong Constructor*******");
}
//静态方法返回创建的对象
public static Singleton getInstance(){
if (null == instance){
synchronized (Singleton.class) {
if (null == instance){
instance = new Singleton();
}
}
}
return instance;
}
public void print(){
System.out.println("*****"+ Thread.currentThread().getName() +"单利类******");
}
}