你的位置:首页 > Java教程

[Java教程]Java单例模式实现的几种方式


单例模式好多书上都是这么写的:

public class SingleTon1 {		private SingleTon1(){		}	private static SingleTon1 instance = null;		public static SingleTon1 getInstance(){		if(instance == null){			instance = new SingleTon1();		} 		return instance;	}}

  但是实际开发中是不会这么写的,因为有一个严重的问题,多线程并发访问的时候,可能会产生多个实例!!

下面列举几个常用的方法:

1.使用synchronized 关键字

package singleton;public class SingleTon1 {			private SingleTon1(){			}	private static SingleTon1 instance = null;		//多线程问题解法一,但是效率不高!因为每次调用都会加锁!	public static synchronized SingleTon1 getInstance(){		if(instance == null){			instance = new SingleTon1();		} 		return instance;	}	public void print(){		System.out.println("thread_id:"+Thread.currentThread().getId());	}		private static Object object = new Object();	//很巧妙的方法,只有在null的时候加锁,之后就不加啦	public static SingleTon1 getInstance2(){				if(instance == null){			synchronized (object){				instance = new SingleTon1();		  }		}		return instance;	}}

 2.加锁

package singleton;import java.util.concurrent.locks.ReentrantLock;public class SingleTon2 {	  private SingleTon2(){			}  private static ReentrantLock lock = new ReentrantLock();	private static SingleTon2 instance = null;			public void print(){		System.out.println("thread_id:"+Thread.currentThread().getId());	}	  public static SingleTon2 getInstance2(){				if(instance == null){			lock.lock();			if(instance == null){ //注意这里还要判断下!!				instance = new SingleTon2();			}		  lock.unlock();		}		return instance;	}}

  3.利用静态变量:

package singleton;public class SingleTon3 {  	public static void print(){		System.out.println("thread_id:"+Thread.currentThread().getId());	}	  public static Nested getNested(){			return Nested.instance;	}  //这个是单例创建的类  static class Nested{   private Nested(){  	}  static Nested instance = new Nested();  }}

以上就是常用的创建单例的模式:

Test测试代码:

package singleton;import singleton.SingleTon3.Nested;public class Test2 {	public static void main(String[] args) {		// TODO Auto-generated method stub		Nested singleton;		Myrunnable mm = new Myrunnable();		Myrunnable m1 = new Myrunnable();				Myrunnable2 m2 = new Myrunnable2();		new Thread(m1).start();		new Thread(m2).start();		if(m1.singleton == m2.singleton){ //是同一个			System.out.println("是同一个");		}else{			System.out.println("不是同一个");		}	 }}	class Myrunnable implements Runnable{		Nested singleton;			@Override			public void run() {				// TODO Auto-generated method stub				singleton = SingleTon3.getNested();				SingleTon3.print();			}	}	 	class Myrunnable2 implements Runnable{		Nested singleton;		@Override		public void run() {			// TODO Auto-generated method stub			singleton = SingleTon3.getNested();			SingleTon3.print();		}  }

输出:

是同一个
thread_id:11
thread_id:10