java 多线程 单例模式

单例模式:

单例模式是指在程序运行过程中,某个类在内存中只有一个对象,即让一个类只能创建一个对象,所以单例模式不能用new关键字创建

单例模式一般分为两种情况,饿汉式和懒汉式

创建单例模式的步骤:

1构造方法私有化private,保证外部访问不到构造方法,否则可以创建无限多个对象,私有化构造方法后系统不再提供默认的构造方法

2创建私有的private静态的static  当前对象类对象(饿汉式)/可见的volitale当前类对象的引用(懒汉式或延时加载)

3对外提供公共的public静态的static访问方法,将单例对象暴漏给外部,让外部能访问到单例类的对象

注意:2中成员变量要是私有的静态的,如果不是静态的,3中的静态方法访问不到这个成员变量.

3中的公共方法必须要是静态的,才可以通过类名.方法名的方式调用该方法

为了防止多线程调用懒汉式创建多个对象,懒汉式的访问方法要设置成同步的synchronized

创建示例:

package chen_chapter_9;

public class SingleTest01 {
	public static void main(String[] args) {
		Single s1 = Single.getInstance();
		Single s2 = Single.getInstance();
		System.out.println(s1 == s2);

		Slone s3 = Slone.getInstance();
		Slone s4 = Slone.getInstance();
		System.out.println(s3 == s4);
	}

}
//懒汉式
class Single {
	// 1私有化构造方法
	private Single() {
	}

	// 2创建当前单例类对象,因为是饿汉,所以先创建对象,为了不被外部访问,要私有化,且静态
	private static Single s = new Single();

	// 3提供给外部能访问的方法,返回该单例模式的对象,因为只能通过类名.方法的方式访问该方法,所以该方法要是静态的
	public static Single getInstance() {
		return s;
	}
}


//饿汉式
class Slone {
	// 1私有化构造方法
	private Slone() {
	}

	// 2创建单例类的引用,不能直接被外面访问,用private,对多线程可见,要用volitale关键字
	private static volatile Slone slone = null;

	// 3提供公共方法,以返回该单例对象
	public static synchronized Slone getInstance() {
		if (slone == null) {
			slone = new Slone();
		}
		return slone;
	}
}
out:
true
true两个对象的内存地址相同,说明是同一个对象

java示例:

java源码提供了一个Runtime类,这个类是一个单例模式,查看部分源码:

public class Runtime {
    private static final Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    /** Don't let anyone else instantiate this class */不能被任何人实例化
    private Runtime() {}
//该函数可以执行windows的一些命令如画图mspaint,关机shutdown, logoff注销命令,
//notepad——–打开记事本,dvdplay——–DVD播放器等
    public Process exec(String command) throws IOException {
        return exec(command, null, null);
    }

使用exec示例:

import java.io.IOException;

public class RuntimeTest01 {
	public static void main(String[] args) {
		Runtime rt = Runtime.getRuntime();
		try {
			rt.exec(" explorer");//打开文件浏览器
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

我们之前用到的Calendar日历类,是抽象类,不能通过new来创建对象,它有getInstance方法,可以使用该方法获得此类型的一个通用对象,但是Calendar类并不是单例模式,所以不是所有私有构造方法、对外通过getInstance方法提供实例的类都是单例模式,Calendar是抽象类

public static Calendar getInstance()
    {
        Locale aLocale = Locale.getDefault(Locale.Category.FORMAT);
        return createCalendar(defaultTimeZone(aLocale), aLocale);
    }
//默认返回当前国家/地区下的日期格式

 简单使用Calendar获取当前年月日:

import java.util.Calendar;

public class CalendarTest01 {

	public static void main(String[] args) {
		Calendar c = Calendar.getInstance();
		System.out.println(c.get(Calendar.YEAR));
		System.out.println(c.get(Calendar.MONTH) + 1);// 0表示1月份
		System.out.println(c.get(Calendar.DAY_OF_MONTH));
	}
}
out:
2018
11
25

参考:http://www.monkey1024.com/javase/688

猜你喜欢

转载自blog.csdn.net/sinat_41132860/article/details/84502411