Person4不把整个方法给同步,只同步创建Person对象的那个方法.
Person4比Person3的线程同步麻烦那么多,效率肯定会更高.因为Person4的下面这段代码永远都只会执行一次.
synchronized (Person4.class) { if(person==null){//双重检查.第一个线程和第二个线程同时跨过了if(person==null){这个门槛,可能相差零点几毫秒. person = new Person4();//初始化是需要一段时间的,尤其是你需要资源的话,资源初始化的话时间会更长,甚至是几秒. //只有person = new Person4()这个方法才是真正需要同步的.person被new的时候创建的时候才需要同步.因为防止不同的进程 //都来创建它.所以是同步的,只有一个线程可以把持. } }
类似于Person3的person = new Person3();永远只会被执行一次.
public static synchronized Person3 getPerson(){ //return new Person(); //return person; if(person==null){ //return new Person2(); person = new Person3();//初始化是需要一段时间的,尤其是你需要资源的话,资源初始化的话时间会更长,甚至是几秒. } return person; }
懒汉式的三种写法比饿汉式都要麻烦一些,但是饿汉式在一开始载入这个类就初始化然后创建类的实例比较耗费资源,但是它的这个线程永远是安全的.不管是多线程还是单线程饿汉式都是安全的.
public static final Person person = new Person();
双重检查是懒汉式的一种,只是对懒汉式的改进.
public class MainClass { public static void main(String[] args) { /* Person per = new Person(); Person per2 = new Person(); per.setName("zhangsan"); per2.setName("lisi"); System.out.println(per.getName()); System.out.println(per2.getName());*/ /* Person per = Person.getPerson(); Person per2 = Person.getPerson(); per.setName("zhangsan"); per2.setName("lisi"); System.out.println(per.getName()); System.out.println(per2.getName());*/ Person2 per = Person2.getPerson(); Person2 per2 = Person2.getPerson(); per.setName("zhangsan"); per2.setName("lisi"); System.out.println(per.getName()); System.out.println(per2.getName()); } }
public class Person { public static final Person person = new Person();//静态的常量,只有一份,而且不能改变它的引用,引用里面的数据还是可以改变的. //类加载的时候初始化的时候赋值.只有一份. //在多线程环境下饿汉式是可以保证只有一份的.因为它永远只有一份,你获得的都是这个Person引用(new Person()). private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } //构造函数私有化 private Person() { } //提供一个全局的静态方法 public static Person getPerson(){ //return new Person(); return person; } }
public class Person2 { private String name; public static Person2 person;//多线程环境下懒汉式不能保证Person引用只有一份,单线程环境下可以保证只有一份Person引用. // public String getName() { return name; } public void setName(String name) { this.name = name; } //构造函数私有化 /* private Person() { }*/ private Person2(){ } //提供一个全局的静态方法 //public static Person getPerson(){ public static Person2 getPerson(){ //return new Person(); //return person; if(person==null){ //return new Person2(); person = new Person2();//初始化是需要一段时间的,尤其是你需要资源的话,资源初始化的话时间会更长,甚至是几秒. } return person; } }
public class Person3 { private String name; public static Person3 person;//多线程环境下懒汉式不能保证Person引用只有一份,单线程环境下可以保证只有一份Person引用. // public String getName() { return name; } public void setName(String name) { this.name = name; } //构造函数私有化 /* private Person() { }*/ private Person3(){ } //提供一个全局的静态方法,使用同步方法 //public static Person getPerson(){ //public static Person3 getPerson(){ public static synchronized Person3 getPerson(){ //return new Person(); //return person; if(person==null){ //return new Person2(); person = new Person3();//初始化是需要一段时间的,尤其是你需要资源的话,资源初始化的话时间会更长,甚至是几秒. } return person; } }
public class Person4 { private String name; public static Person4 person; public String getName() { return name; } public void setName(String name) { this.name = name; } //构造函数私有化 /* private Person() { }*/ private Person4(){ } //提供一个全局的静态方法,使用同步方法 //public static Person getPerson(){ //public static Person3 getPerson(){ public static synchronized Person4 getPerson(){ //return new Person(); //return person; if(person==null){//这个方法并没有同步. //return new Person2(); //synchronized (person) { synchronized (Person4.class) { if(person==null){//双重检查.第一个线程和第二个线程同时跨过了if(person==null){这个门槛,可能相差零点几毫秒. person = new Person4();//初始化是需要一段时间的,尤其是你需要资源的话,资源初始化的话时间会更长,甚至是几秒. //只有person = new Person4()这个方法才是真正需要同步的.person被new的时候创建的时候才需要同步.因为防止不同的进程 //都来创建它.所以是同步的,只有一个线程可以把持. } } } return person; } }