Java单例模式
//先写一个本类的无参构造方法
private Singleton() {}
//懒汉就是先赋值为null
private static Singleton single=null;
//然后进行判断是否是null,在调用的时候如果是null,就new一个对象
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
线程是不安全的,并发情况下可能出现多个实例,保证安全可以添加锁。getInstance添加synchronized修饰,也可以在判断之前添加类锁,synchronized(Singleton.class)。
//先写一个本类的无参构造方法
private Singleton1() {}
//饿汉就是new实例,在返回
private static final Singleton1 single = new Singleton1();
public static Singleton1 getInstance() {
return single;
}
饿汉式在类创建的同时就已经创建好一个静态的对象,以后不再改变,所以是线程安全的。
1. //类似Spring里面的方法,将类名注册,下次从里面直接获取。
2. public class Singleton3 {
3. private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
4. static{
5. Singleton3 single = new Singleton3();
6. map.put(single.getClass().getName(), single);
7. }
8. //保护的默认构造子
9. protected Singleton3(){}
10. //静态工厂方法,返还此类惟一的实例
11. public static Singleton3 getInstance(String name) {
12. if(name == null) {
13. name = Singleton3.class.getName();
14. System.out.println("name == null"+"--->name="+name);
15. }
16. if(map.get(name) == null) {
17. try {
18. map.put(name, (Singleton3) Class.forName(name).newInstance());
19. } catch (InstantiationException e) {
20. e.printStackTrace();
21. } catch (IllegalAccessException e) {
22. e.printStackTrace();
23. } catch (ClassNotFoundException e) {
24. e.printStackTrace();
25. }
26. }
27. return map.get(name);
28. }
29. //一个示意性的商业方法
30. public String about() {
31. return "Hello, I am RegSingleton.";
32. }
33. public static void main(String[] args) {
34. Singleton3 single3 = Singleton3.getInstance(null);
35. System.out.println(single3.about());
36. }
将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从Map直接返回,对于没有登记的,则先登记,然后返回。 其实内部实现还是用的饿汉式单例,因为其中的static方法块,它的单例在类被装载的时候就被实例化了。
代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。