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

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

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

  1. Java中创建对象的几种方式

    Java中创建对象的五种方式: 作为java开发者,我们每天创建很多对象,但是我们通常使用依赖注入的方式管理系统,比如:Spring去创建对象,然而这里有很多创建对象的方法:使用New关键字.使用Cl ...

  2. java产生随机数的几种方式

    java产生随机数的几种方式 一.在j2se里我们可以使用Math.random()方法来产生一个随机数,这个产生的随机数是0-1之间的一个double,我们可以把他乘以一定的数,比如说乘以100,他 ...

  3. Java读写文件的几种方式

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

  4. JAVA解析XML的四种方式

    java解析xml文件四种方式 1.介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这 ...

  5. Java添加事件的四种方式

    Java添加事件的几种方式(转载了codebrother的文章,做了稍微的改动) /** * Java事件监听处理——自身类实现ActionListener接口,作为事件监听器 * * @author ...

  6. java解析xml的几种方式

    java解析xml的几种方式 DOM DOM的全称是Document ObjectModel,也即文档对象模型.在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称D ...

  7. 对Java代码加密的两种方式,防止反编译

    使用Virbox Protector对Java项目加密有两种方式,一种是对War包加密,一种是对Jar包加密.Virbox Protector支持这两种文件格式加密,可以加密用于解析class文件的j ...

  8. Java中创建对象的五种方式

    我们总是讨论没有对象就去new一个对象,创建对象的方式在我这里变成了根深蒂固的new方式创建,但是其实创建对象的方式还是有很多种的,不单单有new方式创建对象,还有使用反射机制创建对象,使用clone ...

  9. java 实现websocket的三种方式

    Java中实现websocket常见有以下三种方式: 使用tomcat的websocket实现,需要tomcat 7.x,JEE7的支持. 使用spring的websocket,spring与webs ...

随机推荐

  1. 【转载】ASP.NET MVC的过滤器

    APS.NET MVC中(以下简称“MVC”)的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理.这时候就用到了过滤器. MVC支持的过滤器 ...

  2. 使用 TOP 限制更新的数据

    可以使用 TOP 子句来限制 UPDATE 语句中修改的行数.当 TOP (n) 子句与 UPDATE 一起使用时,将针对随机选择的 n 行执行删除操作.例如,假设您要为一位高级销售人员减轻销售负担, ...

  3. 水晶报表13.x(Crystal Reports for VS2010)的安装部署经验

    这两天搞安装包真心坎坷,一个问题接一个问题,先是为了实现自定义动作现啃vbs,后面又是安装过程老是报错: 各种搜索.各种尝试,总算搞掂,积累了些经验,分享一下. 首先CR for VS2010的所有东 ...

  4. 使用POI替换word中的特定字符/文字改进版

    package com.xfzx.test.POI.main; import java.io.File; import java.io.FileInputStream; import java.io. ...

  5. 头文件里面的ifndef /define/endif的作用

    c,c++里面,头文件里面的ifndef /define/endif的作用 今天和宿舍同学讨论一个小程序,发现有点地方不大懂······ 是关于头文件里面的一些地方: 例如:要编写头文件test.h ...

  6. 非常不错的Navigation Bar效果

    非常不错的Navigation Bar效果,该源码转载于源码天堂的,大家可以了解一下吧,多视图应用程序中,我们常常使用到自定义UINavigationBar来完成导航条的设置. 源码我就不上传了,大家 ...

  7. linux下MySQL表名忽略大小写设置

    最近公司项目的MySQL数据库要迁移到linux下,部署时日志总是显示报找不到一个表,用MYSQL查看明明有这个表.后来经百度,原来LINUX下的MYSQL默认是区分表名大小写的. 用命令查看当前是否 ...

  8. Java经典实例:在正则表达式中控制大小写

    默认是:区分大小写的: 传递标志参数:Pattern.CASE_INSENSITIVE,以说明匹配时忽略大小写:如果你的代码运行在不同的地区那么你应该再添加一个Pattern.UNICODE_CASE ...

  9. 本机jdbc连接报The user specified as a definer ('root'@'%') does not exist

    昨晚一台测试服务器连接本机的mysql时,有些调用存储过程报"The user specified as a definer ('root'@'%') does not exist" ...

  10. JVM的生命周期、体系结构、内存管理和垃圾回收机制

    一.JVM的生命周期 JVM实例:一个独立运行的java程序,是进程级别 JVM执行引擎:用户运行程序的线程,是JVM实例的一部分 JVM实例的诞生 当启动一个java程序时.一个JVM实例就诞生了, ...