单例模式:
1 public class Person{ 2 public static Person per//定义一个静态变量,用来储存当前类的对象 3 private Person()//构造方法私有化 4 { 5 } 6 public static Person getInstance()//定义一个静态方法,用来获取当前类的实例 7 { 8 if(per==null) 9 { 10 per=this; 11 } 12 return this; 13 } 14 15 } 16 public class Student{ 17 18 Person per=Person.getInstance();//调用静态方法 19 }
思考:如何实现多线程下的单例模式呢?
首先我们要知道单例分为两种模式:
懒汉模式和恶汉模式。
懒汉模式:在类加载的时候不创建实例,运行调用的时候创建类。优点:加载速度快!缺点:在运行的时候获取对象慢!
以上的代码就是懒汉式,符合多线程下的单例模式,但是多线程下一般不使用!
饿汉模式:在类加载时,就完成初始化,所以类加载慢。但是在运行时获取对象的速度快!
1 class Person 2 { 3 private Person person=null; 4 private Person () {} 5 public Person getInstance() 6 { 7 if(person==null) 8 { 9 person =new Person(); 10 } 11 return person; 12 } 13 14 }*/ 15 class Person 16 { 17 private Person person=null; 18 private Person () {} 19 public Person getInstance() 20 { 21 if(person==null) 22 { 23 synchronized(this) 24 { 25 if(person==null) 26 person =new Person(); 27 28 } 29 } 30 51. return person ; 31 } 32 } 33 /* 34 * 35 * 这样在synchronized 线程控制块里面进行多线程的控制,就不会再出现多个线程访问时出现多个对象的情况了. 36 * 还有一点就是外面的person ==null 判断是用来提高效率的,不然第一次都要对锁进行判断,消耗浓资源 37 * 这样可以有次的提高效率 38 * */ 39 public class Single { 40 public static void main(String args[]) 41 { 42 System.out.println("this is java"); 43 } 44 }
在创建实例的方法中有两部判断,一步锁。如果代码进入到了第一步判断直接进入判断,多线程谁先进谁就能先得到对象。如果该线程对象为空,将当前类的对象交给它,继续等待下一个进程的进入。由于使用synchronized锁定,无法同时进入多个线程(排队的形式!)