懒汉式(线程不安全)
1). 起到了懒加载的效果,但是只能在单线程下使用。
2). 如果在多线程下,一个线程进入了if(null == instance)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例,所以在多线程环境下不可使用这种方式。
3). 结论,在实际开发中,不要使用如下这种方式。
public class SingletonTest03 {
public static void main(String[] args){
//Singleton1 s1 = Singleton1.getSingleton1();
//Singleton1 s2 = Singleton1.getSingleton1();
// s1, s2是同一个实例
//System.out.println(s1 == s2);
//System.out.println(s1.hashCode()+" "+s2.hashCode());
T t1 = new T();
new Thread(t1).start();
T t2 = new T();
new Thread(t2).start();
}
}
class T implements Runnable{
public Singleton1 s1 = null;
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Singleton1 s1 = Singleton1.getSingleton1();
System.out.println(s1.hashCode());
}
}
// 懒汉式(线程不安全)
class Singleton1{
// 构造器私有化,外部不能new
private Singleton1(){
}
private static Singleton1 instance;
// 向外部暴露一个静态的公共方法,当使用到该方法时,才去创建instance
// 即懒汉式
public static Singleton1 getSingleton1(){
if(null == instance){
instance = new Singleton1();
}
return instance;
}
}
懒汉式(线程安全, 同步方法)
优缺点:
1). 解决了线程不安全问题.
2). 效率太低了,每个线程在想获得类的实例时候,执行getSingleton1()方法都要进行同步,而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了,方法进行同步效率太低。
3). 结论: 在实际开发中,不推荐使用这种方式。
public class SingletonTest04 {
public static void main(String[] args){
//Singleton1 s1 = Singleton1.getSingleton1();
//Singleton1 s2 = Singleton1.getSingleton1();
// s1, s2是同一个实例
//System.out.println(s1 == s2);
//System.out.println(s1.hashCode()+" "+s2.hashCode());
T t1 = new T();
new Thread(t1).start();
T t2 = new T();
new Thread(t2).start();
System.out.println(t1.s1 == t2.s1);
}
}
class T implements Runnable{
public Singleton1 s1 = null;
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Singleton1 s1 = Singleton1.getSingleton1();
System.out.println(s1.hashCode());
}
}
// 懒汉式(线程安全, 同步方法)
class Singleton1{
// 构造器私有化,外部不能new
private Singleton1(){
}
private static Singleton1 instance;
// 向外部暴露一个静态的公共方法,当使用到该方法时,才去创建instance
// 即懒汉式
// 加入了同步代码,解决线程不安全问题
public static synchronized Singleton1 getSingleton1(){
if(null == instance){
instance = new Singleton1();
}
return instance;
}
}
懒汉式(线程安全, 同步代码块)
同步代码块这种方法连线程安全问题都解决不了,这种同步并不能起到线程同步的作用。假如一个线程进入了if(null == instance)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例
public class SingletonTest05 {
public static void main(String[] args){
//Singleton1 s1 = Singleton1.getSingleton1();
//Singleton1 s2 = Singleton1.getSingleton1();
// s1, s2是同一个实例
//System.out.println(s1 == s2);
//System.out.println(s1.hashCode()+" "+s2.hashCode());
T t1 = new T();
new Thread(t1).start();
T t2 = new T();
new Thread(t2).start();
System.out.println(t1.s1 == t2.s1);
}
}
class T implements Runnable{
public Singleton1 s1 = null;
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Singleton1 s1 = Singleton1.getSingleton1();
System.out.println(s1.hashCode());
}
}
// 懒汉式(线程安全, 同步方法)
class Singleton1{
// 构造器私有化,外部不能new
private Singleton1(){
}
private static Singleton1 instance;
// 向外部暴露一个静态的公共方法,当使用到该方法时,才去创建instance
// 即懒汉式
// 加入了同步代码,解决线程不安全问题
public static Singleton1 getSingleton1(){
if(null == instance){
synchronized(Singleton1.class){
instance = new Singleton1();
}
}
return instance;
}
}