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

时间: 2024-07-28 17:28:24

Java单例模式实现的几种方式的相关文章

Java创建Timestamp的几种方式

1.java创建Timestamp的几种方式 Timestamp time1 = new Timestamp(System.currentTimeMillis()); Timestamp time2 = new Timestamp(new Date().getTime()); Timestamp time3 = new Timestamp(Calendar.getInstance().getTimeInMillis()); //不建议使用 Timestamp time4 = new Timest

Java中创建对象的几种方式

Java中创建对象的五种方式: 作为java开发者,我们每天创建很多对象,但是我们通常使用依赖注入的方式管理系统,比如:Spring去创建对象,然而这里有很多创建对象的方法:使用New关键字.使用Class类的newInstance方法.使用Constructor类的newInstance方法.使用Clone方法.使用反序列化. 使用new关键字:这是我们最常见的也是最简单的创建对象的方式,通过这种方式我们还可以调用任意的够赞函数(无参的和有参的).比如:Student student = ne

Java读写文件的几种方式

自工作以后好久没有整理Java的基础知识了.趁有时间,整理一下Java文件操作的几种方式.无论哪种编程语言,文件读写操作时避免不了的一件事情,Java也不例外.Java读写文件一般是通过字节.字符和行三种方式来进行文件的操作. import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.F

java产生随机数的几种方式

java产生随机数的几种方式 一.在j2se里我们可以使用Math.random()方法来产生一个随机数,这个产生的随机数是0-1之间的一个double,我们可以把他乘以一定的数,比如说乘以100,他就是个100以内的随机,这个在j2me中没有. 二.在java.util这个包里面提供了一个Random的类,我们可以新建一个Random的对象来产生随机数,他可以产生随机整数.随机float.随机double,随机long,这个也是我们在j2me的程序里经常用的一个取随机数的方法. 三.在我们的S

Java开启线程的两种方式

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.ios培训..Net培训</a>.期待与您交流!------ Java开启线程的两种方式: 方式一:成为线程(Thread)的儿子,即继承Thread类简单代码如下:class Student extends Thread{Student(String name){super(name);}public

java.util.Arrays.sort两种方式的排序(及文件读写练习)

import java.io.*; import java.util.*; public class SortTest{ public static void main(String args[]) throws IOException, ClassNotFoundException { FileReader InWord = new FileReader(new File("words.txt")); BufferedReader in = new BufferedReader(In

JAVA中断迭代的几种方式

JAVA中断迭代的几种方式 本文总结一下JAVA中中断迭代的几个关键字的用法,return就不说了,重点说一下break和continue以及JAVA中怎样实现其他语言中的goto关键字的用法. break和continue的区别 两者都有跳出循环的作用,不同的是break跳出循环后,直接终止了for或者while循环,不会执行后面的迭代,而continue跳出循环指的是跳出本次迭代,接着执行下一次迭代. goto介绍 goto起源于汇编语言的程序控制,若A成立,则跳到这里,否则跳到那里. 尽管

几种排序算法及Java实现排序的几种方式

几种排序算法 下面的例子介绍了4种排序方法: 冒泡排序, 选择排序, 插入排序, 快速排序 1 package date201709.date20170915; 2 3 public class SortUtil { 4 5 private static int quickSortTimes = 1; 6 7 /** 8 * 冒泡排序:<br> 9 * 两层循环,每次循环比较前后两个元素,如果他们的顺序错误就把他们交换过来,一次循环后最终会把最大的数沉到数列的末端<br> 10 *

java连接Hive的几种方式

测试环境 Hadoop 0.20.2版本.Hive-0.5.0版本.JDK1.6 1.一般来说我们对hive的操作都是通过cli来进行,也就是Linux的控制台,但是,这样做本质上是每个连接都存放一个元数据,各个之间都不相同,所以,对于这样的模式我建议是用来做一些测试比较合适,并不适合做产品的开发和应用. 2.JDBC连接的方式,当然还有其他的连接方式,比如ODBC等, 这种方式很常用,可以在网上随便找到,就不再累赘了. 不稳定,经常会被大数据量冲挂,不建议使用. 3.这种方式是直接利用Hive