`
programmer_Q
  • 浏览: 5657 次
社区版块
存档分类
最新评论

多线程验证 懒汉式单例模式可能会出现不单例的情况

阅读更多
package ThreadDemo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

//懒汉式单例,线程不安全的,使用同步机制

//对于一般的方法内,使用同步代码块,可以考虑使用this
//对于静态方法而言,使用当前类本身充当锁

/*JAVA类首次装入时,会对静态成员变量或方法进行一次初始化,但方法不被调用是不会执行的,
 *  静态成员变量和静态初始化块级别相同,非静态成员变量和非静态初始化块级别相同。

 先初始化父类的静态代码--->初始化子类的静态代码-->
 初始化父类的非静态代码--->初始化父类构造函数--->
 初始化子类非静态代码--->初始化子类构造函数
 */

public class TestSingleton {
	public static void main(String[] args) throws Exception {
		
		List<Singleton> singletonlist= new ArrayList<Singleton>();
		Set<Singleton> singletonSet= new HashSet<Singleton>();
		
		List<Callable> callableList= new ArrayList<Callable>();
		List<Future> futureList= new ArrayList<Future>();
		// 获取多线程的返回值
		// 1创建一个线程池
		ExecutorService pool = Executors.newFixedThreadPool(1000);
		
		for(int i=0;i<1000;i++){
			//2创建有返回值的任务线程
			Callable c1 = new ThreadTestSingle();
			// 3执行任务并获取Future对象
			Future f1 = pool.submit(c1);
			//4从Future对象上获取任务的返回值
			singletonlist.add((Singleton) f1.get());
			singletonSet.add((Singleton) f1.get());
		}
		System.out.println(singletonlist.size());
		System.out.println(singletonlist.get(0)==singletonlist.get(1));
		System.out.println(singletonSet.size());

		// 5关闭线程池
		pool.shutdown();
	}
}

class Singleton {
	private Singleton() {
	}

	private static Singleton instance = null;

	public static Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}

/* 有返回值的多线程 */
class ThreadTestSingle implements Callable {

	@Override
	public Singleton call() throws Exception {
		// TODO Auto-generated method stub
		return Singleton.getInstance();
	}

}

执行结果是:

1000

true

1

 

本来想循环创建多线程,但是因为for循环是先后的,所有,其实只是第一个循环去创建的,就当学习下有返回值的多线程吧。。。 如何用for循环去验证?应该不好使吧。。

 

 倒是下面的 这种,基本都能测试出来,不是相同对象

package ThreadDemo;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

//懒汉式单例,线程不安全的,使用同步机制

//对于一般的方法内,使用同步代码块,可以考虑使用this
//对于静态方法而言,使用当前类本身充当锁

/*JAVA类首次装入时,会对静态成员变量或方法进行一次初始化,但方法不被调用是不会执行的,
 *  静态成员变量和静态初始化块级别相同,非静态成员变量和非静态初始化块级别相同。

先初始化父类的静态代码--->初始化子类的静态代码-->
初始化父类的非静态代码--->初始化父类构造函数--->
初始化子类非静态代码--->初始化子类构造函数
*/


public class TestSingleton2 {	
	public static void main(String[] args) throws Exception {
		//获取多线程的返回值
		 //1创建一个线程池 
        ExecutorService pool = Executors.newFixedThreadPool(2); 
        //2创建两个有返回值的任务 
        Callable c1 = new ThreadTestSingle(); 
        Callable c2 = new ThreadTestSingle(); 
        //3执行任务并获取Future对象 
        Future f1 = pool.submit(c1); 
        Future f2 = pool.submit(c2); 
        //4从Future对象上获取任务的返回值,并输出到控制台 
        Singleton singleton1=(Singleton) f1.get();
        Singleton singleton21=(Singleton) f2.get();
        System.out.println();
        
 
		System.out.println(singleton1==singleton21);
		//5关闭线程池 
        pool.shutdown(); 
	}
}

class Singleton{
	private Singleton(){}
	private static Singleton instance=null;
	public static Singleton getInstance(){
		
/*				if (instance == null) {
					synchronized (Singleton.class) {
						if(instance==null)
						instance = new Singleton();
					}
				}*/
		
		if(instance==null){
			instance = new Singleton();
		}
		return instance;
	}
}

/*有返回值的多线程*/
class ThreadTestSingle implements Callable{

	public Singleton call() throws Exception {
		// TODO Auto-generated method stub
		return Singleton.getInstance();
	}
	
}

 

打印结果大多数都是false

 

 

分享到:
评论

相关推荐

    设计模式——单例模式

    **设计模式——单例模式** 在软件工程中,设计模式是一种在特定场景下解决常见问题的标准方案,可以被...同时,需要注意的是,过度依赖单例可能导致系统设计过于紧密,不利于测试和扩展,因此在设计时需要权衡利弊。

    Java中懒汉单例设计模式线程安全测试

    Java中懒汉单例设计模式线程安全测试,单例设计模式的测试

    2种单例模式:1赖汉式:2饿汉式

    饿汉式单例的特点是类加载时就完成了实例化,确保了线程安全,但可能会造成资源浪费,因为无论是否使用,都会立即创建单例对象。实现方式通常是将单例对象作为静态常量,如下所示: ```java public class ...

    C++实现单例模式(懒汉式)源码

    在C++中,实现单例模式有多种方式,这里我们将聚焦于懒汉式(Lazy Initialization)的实现。懒汉式单例的特点是延迟初始化,即只有在第一次使用时才会创建实例,这有助于提高程序的运行效率。 一、懒汉式单例模式的...

    使用单例模式创建学生管理系统(饿汉式、懒汉式)

    但是,如果不进行同步控制,懒汉式在多线程环境下可能会创建多个实例,因此通常采用双重检查锁定(Double-Checked Locking,DCL)来实现线程安全的懒汉式单例: ```java public class Singleton { private ...

    java 单例模式(懒汉式与饿汉式)

    * 单例模式可能会导致资源浪费,因为饿汉式单例可能会在类加载时就创建单例对象。 * 单例模式可能会导致线程安全问题,如果不正确地实现单例模式,可能会导致线程安全问题。 单例模式是一种常用的软件设计模式,它...

    多线程单例模式并发访问

    总结起来,多线程环境下的单例模式实现需要注意线程安全问题,尤其是懒汉式单例,需要采取适当的同步措施来防止多线程环境下的实例化问题。此外,对于不同场景的需求,可以选择不同的实现方式来优化性能和资源使用。

    设计模式——单例模式(懒汉模式)

    懒汉式单例模式的特点是延迟加载,即只有在第一次使用时才会创建实例,这样可以提高系统性能,因为如果单例对象从未被使用,那么就不会消耗内存。 在Java中,懒汉式的单例模式通常通过双重检查锁定(Double-Check ...

    Java设计模式之单例模式的七种写法

    这种写法的问题是它没有考虑线程安全问题,在并发环境下很可能出现多个 Singleton1 实例。 2、懒汉式单例(加同步) public class Singleton2 { private Singleton2() {} private static Singleton2 single = ...

    单例模式(懒汉式,饿汉式)

    缺点是由于实例化过程可能会受到多线程的影响,需要采取措施保证线程安全。在给定的代码片段中,`Singleton2` 类实现了懒汉式单例模式: ```java public class Singleton2 { // 私有构造函数,防止外部直接实例化 ...

    线程安全的单例模式

    例如,在某些情况下,对象创建过程可能会被JVM指令重排序,导致线程A创建的对象尚未完全构造完成,而线程B已经能够访问到这个半成品对象。为了避免这个问题,需要使用 `volatile` 关键字来标记 `singObj` 变量,确保...

    Java多线程-解决单例模式中的懒汉式的线程安全问题

    ### Java多线程—解决单例模式中的懒汉式的线程安全问题 #### 一、单例设计模式的线程安全问题 ##### (1)饿汉式没有线程安全问题 **饿汉式**是一种非常典型的单例模式实现方式,其特点是在类加载时就完成了实例...

    C++单例模式懒汉式和饿汉式

    在多线程环境下,如果没有适当的同步控制,多个线程可能会同时进入`instance()`方法,从而创建多个实例,破坏了单例模式的基本原则。对于C++中的懒汉式单例,如下所示: ```cpp class LazySingleton { protected: ...

    Java 单例模式 懒汉模式

    Java 单例模式 懒汉模式 //懒汉式 多线程中不可以保证是一个对象

    懒汉式单例模式的实现案例

    单例模式的特点:从系统启动到终止,整个过程只会产生一个实例。因为单例提供了唯一实例的全局访问方法,所以它可以优化共享资源的访问,避免对象的频繁创建和销毁,从而可以提高性能。单例模式常见的应用场景如下:...

    java 单例模式(懒汉式与饿汉式).docx

    懒汉式单例是一种延迟加载的单例模式,它只有当调用 getInstance 的时候,才会初始化这个单例。这种模式的优点是可以减少资源的加载和性能上的负担,但是它需要使用 synchronized 关键字来确保线程安全。 以下是...

    设计模式单例模式

    2. **饿汉式**(Eager Initialization):饿汉式单例模式是在类加载时就完成了初始化,因此,它保证了线程安全,但可能会造成资源浪费,因为无论是否使用,都会在程序启动时创建对象。Java中常通过静态内部类实现...

    23钟设计模式之单例模式

    但是,如果在多线程环境下,没有正确处理同步问题,可能导致多个线程同时创建单例,破坏单例的唯一性。例如,文章中提到的简单懒汉式,就存在这个问题。 ```java public class Singleton { private static ...

    java + 单例模式 + 懒汉式 + 资源

    在Java中,单例模式有多种实现方式,其中最常用的两种是饿汉式(Eager Initialization)和懒汉式(Lazy Initialization)。本文将深入探讨懒汉式单例模式,以及它与饿汉式的区别。 ### 懒汉式单例模式 懒汉式的...

Global site tag (gtag.js) - Google Analytics