这里有新鲜出炉的 Java 并发编程示例,程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称.
这篇文章主要以图文结合的方式为大家详细介绍了 Java 单例模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
PS: 首先我们要先知道什么是单例,为什么要用单例,用的好处是什么等问题来看.
1:java 中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例,饿汉式单例
单例模式有以下特点:
1,单例类只能有一个实例.
2,单例类必须自己创建自己的唯一实例.
3,单例类必须给所有其他对象提供这一实例.
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池,缓存,日志对象,对话框,打印机,显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打印机,但只能有一个 Printer Spooler,以避免两个打印作业同时输出到打印机中.每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用.总之,选择单例模式就是为了避免不一致状态,避免政出多头.
2:懒汉式
先把单例类写出来
这里直接上代码,代码中有详解
public class SingletonTest {
//懒汉式单例类.在第一次调用的时候实例化自己
private SingletonTest() {}
private static SingletonTest single = null;
//静态工厂方法
public static SingletonTest getInstance() {
if (single == null) {
single = new SingletonTest();
System.out.println("创建一次");
}
return single;
}
public void show() {
System.out.println("我是show");
}
}
public class SingletonTest2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//故意写获取两次,创建两个对象
SingletonTest singleton = SingletonTest.getInstance();
SingletonTest singleton2 = SingletonTest.getInstance();
//Singleton对象只创建一次,但是写两次还是可以的,而且方法都是可以调用的,但是看下面
singleton.show();
singleton2.show();
//两个对象的表现形式一样
if (singleton == singleton2) {
System.out.println("该对象的字符串表示形式:");
System.out.println("singleton :" + singleton.toString());
System.out.println("singleton2:" + singleton2.toString());
}
由上面的图可以看出就算多创建几个对象,在底部也是只有一个 singleton 对象实例,而且创建出来的对象的字符串表现形式也是一样的,有的人肯定有疑问,那平常两个对象是什么样子的呢,我下面给你解释说明,在这之前我写说一下这个懒汉式需要注意的地方,它是线程不安全的,并发环境下很可能出现多个 Singleton 实例,有很多方法可以解决,比如说同步锁,静态内部类等,这里主要说静态内部类,这个比较好点,
调用:
public class Singleton3 {
private static class SingletonHolder {
private static final Singleton3 INSTANCE = new Singleton3();
}
private Singleton3() {}
public static final Singleton3 getInstance() {
System.out.println("singleton创建");
return SingletonHolder.INSTANCE;
}
}
结果图:
Singleton3 singleton3 = Singleton3.getInstance();
Singleton3 singleton4 = Singleton3.getInstance();
if (singleton3 == singleton4) {
System.out.println("该对象的字符串表示形式:");
System.out.println("singleton3:" + singleton3.toString());
System.out.println("singleton4:" + singleton4.toString());
}
这里我也是创建了两个对象来说明,神奇的是打印了两次 singleton 创建,这难道是又创建成功了的对象吗?答案是:虽然打印了两次,对象名也有两个,但是该对象的字符串表示形式还是一样的,而且大家都知道 static 的用法,就是在类被加载的同时该 singleton 对象就已经被创建,后期不会再被创建,就算后期自己又调用了 getInstance()方法,但底层还是公用的一个 Singleton 对象.
同样,我写了一个普通的类,来同时创建两个对象,并且打印他们的 toString()方法,如下:
QuBie qb1 = new QuBie();
QuBie qb2 = new QuBie();
if (qb1 == qb2) {
System.out.println("该对象的字符串表示形式:");
System.out.println("singleton3:" + qb1.toString());
System.out.println("singleton4:" + qb2.toString());
} else {
System.out.println("该对象的字符串表示形式:");
System.out.println("singleton3:" + qb1.toString());
System.out.println("singleton4:" + qb2.toString());
}
由此可看出来对象的字符串表示形式是不一样的
3:饿汉式单例
饿汉式单例类. 在类初始化时,已经自行实例化
因为这本身就是 static 修饰的方法,所以是在类加载的时候被创建,后期不会再改变,所以线程是安全的.
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
来源: http://www.phperz.com/article/18/0117/352784.html