单例模式多种情况

先看饿汉模式:

package com.zyzs.Singleton;

public class Singleton {
	private static Singleton singleton =new Singleton();
	
	//获取实例对象
	public static Singleton getInstance(){
		return singleton;
	}
	
	public static void main(String[] args) {
		//此方法不存在线程安全问题--不存原子操作
		System.out.println(Singleton.getInstance());
		System.out.println(Singleton.getInstance());
	}
}

优缺点:此模式不存在线程安全性问题,因为对象再初始化时候已经加入内存,线程只对对象进行读取操作,不存在原子操作,但是对于加载大的对象或者比较耗费性能的对象而言,饿汉模式显然会占用更多资源。

懒汉模式:

第一种情况:

package com.zyzs.Singleton;

import java.util.ArrayList;
import java.util.List;
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;
import java.util.concurrent.ThreadPoolExecutor;

public class Singleton2 {
	private static Singleton2 singleton;
	
	//获取实例对象
	public static Singleton2 getInstance(){
		if(singleton==null){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			singleton=new Singleton2();
		}
		return singleton;
	}
	
	public static void main(String[] args) {
		
		ExecutorService executorService =Executors.newCachedThreadPool();  
		List<Future<String>> resultList = new ArrayList<Future<String>>();  

        // 创建10个任务并执行  
        for (int i = 0; i < 10; i++) {  
            // 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中  
            Future<String> future = (Future<String>) executorService.submit(new TaskWithResult());  
            // 将任务执行结果存储到List中  
            resultList.add(future);  
        }  
        executorService.shutdown();  

        // 遍历任务的结果  
        for (Future<String> fs : resultList) {  
            try {  
                System.out.println(fs.get()); // 打印各个线程(任务)执行的结果  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } catch (ExecutionException e) {  
                executorService.shutdownNow();  
                e.printStackTrace();  
                return;  
            }  
        }  
	}
}


class TaskWithResult implements Callable<String> {

	@Override
	public String call() throws Exception {
		return Singleton2.getInstance().toString();
	}
	
}

1.附带测试案例,此对象会存在线程安全问题,不建议在多线程环境下使用

第二种情况:

package com.zyzs.Singleton;

import java.util.ArrayList;
import java.util.List;
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;
import java.util.concurrent.ThreadPoolExecutor;

public class Singleton3 {
	private static Singleton3 singleton;
	
	//获取实例对象
	public static synchronized Singleton3 getInstance(){
		//此处存在自旋操作--比较好性能--和单例没有区别
		if(singleton==null){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			singleton=new Singleton3();
		}
		return singleton;
	}
	
	public static void main(String[] args) {
		
		ExecutorService executorService =Executors.newCachedThreadPool();  
		List<Future<String>> resultList = new ArrayList<Future<String>>();  

        // 创建10个任务并执行  
        for (int i = 0; i < 10; i++) {  
            // 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中  
            Future<String> future = (Future<String>) executorService.submit(new TaskWithResult3());  
            // 将任务执行结果存储到List中  
            resultList.add(future);  
        }  
        executorService.shutdown();  

        // 遍历任务的结果  
        for (Future<String> fs : resultList) {  
            try {  
                System.out.println(fs.get()); // 打印各个线程(任务)执行的结果  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } catch (ExecutionException e) {  
                executorService.shutdownNow();  
                e.printStackTrace();  
                return;  
            }  
        }  
	}
}


class TaskWithResult3 implements Callable<String> {

	@Override
	public String call() throws Exception {
		return Singleton3.getInstance().toString();
	}
	
}

此方法虽然能保证线程安全,但是对方法的加锁会导致线程的自旋操作,会占用较多资源,耗费性能,建议使用第三中

 

第三种:

package com.zyzs.Singleton;

import java.util.ArrayList;
import java.util.List;
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;
import java.util.concurrent.ThreadPoolExecutor;

public class Singleton4 {
	private static Singleton4 singleton;
	
	//获取实例对象
	public static  Singleton4 getInstance(){
		//此处存在自旋操作--比较好性能--和单例没有区别
		if(singleton==null){
			synchronized(Singleton4.class){
				if(singleton==null){
					singleton=new Singleton4();
				}
			}
			
		}
		return singleton;
	}
	
	public static void main(String[] args) {
		
		ExecutorService executorService =Executors.newCachedThreadPool();  
		List<Future<String>> resultList = new ArrayList<Future<String>>();  

        // 创建10个任务并执行  
        for (int i = 0; i < 10; i++) {  
            // 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中  
            Future<String> future = (Future<String>) executorService.submit(new TaskWithResult4());  
            // 将任务执行结果存储到List中  
            resultList.add(future);  
        }  
        executorService.shutdown();  

        // 遍历任务的结果  
        for (Future<String> fs : resultList) {  
            try {  
                System.out.println(fs.get()); // 打印各个线程(任务)执行的结果  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } catch (ExecutionException e) {  
                executorService.shutdownNow();  
                e.printStackTrace();  
                return;  
            }  
        }  
	}
}


class TaskWithResult4 implements Callable<String> {

	@Override
	public String call() throws Exception {
		return Singleton4.getInstance().toString();
	}
	
}

此种方式在方法块进行加锁,缩小加锁范围,使用双重验证进行实例初始化,建议使用此方法

了解更多加微信 aa544731152,拉你入群

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值