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 public class ...
在C++中,实现单例模式有多种方式,这里我们将聚焦于懒汉式(Lazy Initialization)的实现。懒汉式单例的特点是延迟初始化,即只有在第一次使用时才会创建实例,这有助于提高程序的运行效率。 一、懒汉式单例模式的...
但是,如果不进行同步控制,懒汉式在多线程环境下可能会创建多个实例,因此通常采用双重检查锁定(Double-Checked Locking,DCL)来实现线程安全的懒汉式单例: ```java public class Singleton { private ...
* 单例模式可能会导致资源浪费,因为饿汉式单例可能会在类加载时就创建单例对象。 * 单例模式可能会导致线程安全问题,如果不正确地实现单例模式,可能会导致线程安全问题。 单例模式是一种常用的软件设计模式,它...
总结起来,多线程环境下的单例模式实现需要注意线程安全问题,尤其是懒汉式单例,需要采取适当的同步措施来防止多线程环境下的实例化问题。此外,对于不同场景的需求,可以选择不同的实现方式来优化性能和资源使用。
懒汉式单例模式的特点是延迟加载,即只有在第一次使用时才会创建实例,这样可以提高系统性能,因为如果单例对象从未被使用,那么就不会消耗内存。 在Java中,懒汉式的单例模式通常通过双重检查锁定(Double-Check ...
这种写法的问题是它没有考虑线程安全问题,在并发环境下很可能出现多个 Singleton1 实例。 2、懒汉式单例(加同步) public class Singleton2 { private Singleton2() {} private static Singleton2 single = ...
缺点是由于实例化过程可能会受到多线程的影响,需要采取措施保证线程安全。在给定的代码片段中,`Singleton2` 类实现了懒汉式单例模式: ```java public class Singleton2 { // 私有构造函数,防止外部直接实例化 ...
例如,在某些情况下,对象创建过程可能会被JVM指令重排序,导致线程A创建的对象尚未完全构造完成,而线程B已经能够访问到这个半成品对象。为了避免这个问题,需要使用 `volatile` 关键字来标记 `singObj` 变量,确保...
### Java多线程—解决单例模式中的懒汉式的线程安全问题 #### 一、单例设计模式的线程安全问题 ##### (1)饿汉式没有线程安全问题 **饿汉式**是一种非常典型的单例模式实现方式,其特点是在类加载时就完成了实例...
在多线程环境下,如果没有适当的同步控制,多个线程可能会同时进入`instance()`方法,从而创建多个实例,破坏了单例模式的基本原则。对于C++中的懒汉式单例,如下所示: ```cpp class LazySingleton { protected: ...
Java 单例模式 懒汉模式 //懒汉式 多线程中不可以保证是一个对象
单例模式的特点:从系统启动到终止,整个过程只会产生一个实例。因为单例提供了唯一实例的全局访问方法,所以它可以优化共享资源的访问,避免对象的频繁创建和销毁,从而可以提高性能。单例模式常见的应用场景如下:...
懒汉式单例是一种延迟加载的单例模式,它只有当调用 getInstance 的时候,才会初始化这个单例。这种模式的优点是可以减少资源的加载和性能上的负担,但是它需要使用 synchronized 关键字来确保线程安全。 以下是...
2. **饿汉式**(Eager Initialization):饿汉式单例模式是在类加载时就完成了初始化,因此,它保证了线程安全,但可能会造成资源浪费,因为无论是否使用,都会在程序启动时创建对象。Java中常通过静态内部类实现...
但是,如果在多线程环境下,没有正确处理同步问题,可能导致多个线程同时创建单例,破坏单例的唯一性。例如,文章中提到的简单懒汉式,就存在这个问题。 ```java public class Singleton { private static ...
在Java中,单例模式有多种实现方式,其中最常用的两种是饿汉式(Eager Initialization)和懒汉式(Lazy Initialization)。本文将深入探讨懒汉式单例模式,以及它与饿汉式的区别。 ### 懒汉式单例模式 懒汉式的...