`

java单例模式在多线程环境下的测试

    博客分类:
  • java
 
阅读更多

java单例模式在多线程环境下的测试,进攻自己学习和复习用.

1. 不加双重判断, 会生成2个不同的对象. 代码如下:

 

package com.thred;

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestSingleton {

	private static TestSingleton s = null;
	
	private TestSingleton() {}

	public static TestSingleton getInstance() {
		if (s == null) {
			System.out.println( new Date() + " " + Thread.currentThread().getName() + "-1->" +  s);
			try {
				Thread.sleep(1);
				System.out.println( new Date() + " " + Thread.currentThread().getName() + "-2->" +  s);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized (TestSingleton.class){
				//if(s == null){
					System.out.println( new Date() + " " + Thread.currentThread().getName() + "-3->" +  s);
					s = new TestSingleton();
					System.out.println( new Date() + " " + Thread.currentThread().getName() + "-4->" +  s);
				//}else{
				//	System.out.println("s isn't null");
				//}
			}
			
		}
		return s;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		ExecutorService service = Executors.newFixedThreadPool(10);
		for(int i = 0 ;i < 2;i++){
			service.submit(new Runnable(){
				public void run(){
					String str =   new Date() +" " +  Thread.currentThread().getName() + "-run invoke->" +  TestSingleton.getInstance().toString();
					System.out.println(str);
				}
			});
		}
	}
}

 

测试结果,会生成2个不同的对象,不是单例,在第四步的没加判断会new 对象.

Mon Jul 23 22:22:54 CST 2012 pool-1-thread-1-1->null
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-2-1->null
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-1-2->null
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-1-3->null
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-1-4->com.thred.TestSingleton@fa7e74
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-1-run invoke->com.thred.TestSingleton@fa7e74
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-2-2->com.thred.TestSingleton@fa7e74
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-2-3->com.thred.TestSingleton@fa7e74
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-2-4->com.thred.TestSingleton@133796
Mon Jul 23 22:22:54 CST 2012 pool-1-thread-2-run invoke->com.thred.TestSingleton@133796

 

2.加双重判断: 在同步代码块中加入判断,只贴出不同的部分.

 

synchronized (TestSingleton.class){
	if(s == null){
		System.out.println( new Date() + " " 
			+ Thread.currentThread().getName() + "-3->" +  s);
		s = new TestSingleton();
		System.out.println( new Date() + " " 
			+ Thread.currentThread().getName() + "-4->" +  s);
	}else{
		System.out.println("s isn't null");
	}
}

 

 

测试结果: 返回同一个对象,是单例

Mon Jul 23 22:27:11 CST 2012 pool-1-thread-2-1->null
Mon Jul 23 22:27:11 CST 2012 pool-1-thread-1-1->null
Mon Jul 23 22:27:11 CST 2012 pool-1-thread-2-2->null
Mon Jul 23 22:27:11 CST 2012 pool-1-thread-2-3->null
Mon Jul 23 22:27:11 CST 2012 pool-1-thread-2-4->com.thred.TestSingleton@183f74d
Mon Jul 23 22:27:11 CST 2012 pool-1-thread-2-run invoke->com.thred.TestSingleton@183f74d
Mon Jul 23 22:27:11 CST 2012 pool-1-thread-1-2->com.thred.TestSingleton@183f74d
s isn't null
Mon Jul 23 22:27:11 CST 2012 pool-1-thread-1-run invoke->com.thred.TestSingleton@183f74d

 

 结论:在写单例的时候一定要加上双重判断呀~~切记

分享到:
评论

相关推荐

    使用Java单例模式实现一个简单的日志记录器.txt

    1. **懒汉式(线程不安全)**:实例化发生在getInstance()方法中,但在多线程环境下可能造成多个实例的问题。 2. **懒汉式(线程安全)**:通过synchronized关键字保证线程安全。 3. **饿汉式**:在类加载时就完成了...

    java单例模式的例子

    Java单例模式是一种常见...在实际开发中,应谨慎使用单例模式,尤其是在多线程环境和需要考虑可测试性的场景下,要权衡其利弊。同时,考虑到Java 9及更高版本中的模块化系统,单例模式的使用也需要结合模块化进行考量。

    java单例模式在android中的应用

    需要注意的是,虽然单例模式在很多情况下都很实用,但也有一些潜在的问题,如单例的生命周期与应用程序一致,可能导致资源无法释放,增加内存泄漏的风险。此外,过度依赖单例可能导致代码之间的紧密耦合,不利于测试...

    Java单例模式.pdf

    Java单例模式是设计模式中的一种,在软件开发中扮演着重要的角色。单例模式的目的是保证一个类仅有一个实例,并且提供一个全局访问点。在Java中实现单例模式有多种方法,主要包括懒汉式、饿汉式、注册式(使用容器)...

    java中的单例模式

    单例模式是设计模式中的一种,它在Java编程中被广泛应用,特别是在需要全局共享资源或者控制实例数量的情况下。单例模式的基本思想是确保一个类在任何情况下都只有一个实例,并提供一个全局访问点来获取这个唯一的...

    java单例模式代码实例

    在第一次调用getInstance()时才创建实例,但线程不安全,多线程环境下可能导致多个实例。 ```java public class Singleton { private static Singleton instance; private Singleton() {} public static ...

    设计模式之单例模式(结合工厂模式)

    在Java中,为了确保多线程环境下的正确性,我们可以使用synchronized关键字来保证同步,但这会引入性能开销。DCL模式通过在实例化单例时使用 volatile 关键字和双层检查,解决了这个问题。volatile关键字保证了多...

    Java实现单例模式[汇编].pdf

    由于实例在类加载时就已经创建,所以即使没有使用,内存空间也被占用了,但这也保证了在多线程环境下的安全性,提高了性能。 3. **登记式单例**: 登记式单例是一种更灵活的实现方式,它维护了一个存储所有单例...

    7种单例模式

    下面将详细介绍七种常见的单例模式实现方式,并结合多线程环境和反序列化测试进行讨论。 1. **饿汉式单例**: 这是最简单的单例实现,它在类加载时就创建了实例,因此是线程安全的。 ```java public class ...

    设计模式——单例模式

    这里的 `getInstance()` 方法使用了 `synchronized` 关键字进行同步,保证了在多线程环境下的线程安全。但是,同步操作会降低性能,因为每次调用都需要进行锁的获取和释放。 为了解决懒汉式单例模式的性能问题,有...

    java-单例模式几种写法

    单例模式是软件设计模式中的一种,用于控制类的实例化过程,确保一个类只有一个实例,并提供全局访问点。...同时,需要注意的是,单例模式虽然常用,但在某些情况下可能不适合,如当需要多个实例或者类需要被继承时。

    设计模式-单例模式

    这是最简单的一种实现方式,它在类加载时就完成了实例化,避免了多线程同步问题。 ```java public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() {} ...

    java单例模式.doc.doc

    虽然单例模式在某些场景下很有用,但过度使用或在不适用的场景下使用可能会导致设计复杂性增加、测试困难以及难以解耦等问题。在设计时应根据实际情况选择是否使用单例模式。 总结起来,Java 单例模式是一种控制类...

    Java单例模式[定义].pdf

    但是,这种方式在多线程环境下存在线程安全问题,如果不进行同步控制,可能会创建多个实例。在上述代码中,`getInstance()`方法使用了`synchronized`关键字进行同步,确保了线程安全,但这也可能导致性能下降,因为...

    多核多线程下java设计模式性能提升.pdf

    总结来说,本文档通过介绍单例模式在多核多线程环境下的性能提升方法,探讨了Java设计模式在现代大型系统应用中的优化策略,并对JDK未来的设计模式实现提出期望,为Java开发人员提供了宝贵的技术指导和参考。

    单例模式.ppt

    但是这种方式在多线程环境下不安全,可能导致多个线程各自创建一个实例。尽管如此,它具有惰性实例化的优点,即只有在第一次需要时才创建实例。 2. **安全的线程实现**: 在多线程环境下,为了解决简单实现的问题...

Global site tag (gtag.js) - Google Analytics