并发编程:并发设计:使用延迟初始化预防问题

目录

延迟初始化

一、主程序

二、正确的预防并发问题方案

三、高并发时会出错的延迟初始化方案

四、模拟并发的任务

五、执行结果


延迟初始化

延迟初始化是一种编程技术,延迟对象的创建,直到第一次被使用。

  • 主要优点:节省内存开销。
  • 主要缺点:性能不是很好。

 

一、主程序

package xyz.jangle.thread.test.nxi_8.lazyinit;

/**
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年10月29日 下午4:46:15
 * 
 */
public class M {

	public static void main(String[] args) {

		for (int i = 0; i < 29; i++) {
			var task = new Task();
			var thread = new Thread(task);
			thread.start();
		}

	}

}

二、正确的预防并发问题方案

package xyz.jangle.thread.test.nxi_8.lazyinit;

/**
 * 使用内部静态类的静态final属性,解决高并发时,错误地创建N+个对象。
 * 
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年10月29日 下午4:46:46
 * 
 */
public class DBConnectionOK {

//	private static DBConnectionOK dbc;

	private DBConnectionOK() {
		System.out.println(Thread.currentThread().getName() + ": Connection created.");
	}

	private static class LazyDBConnection {
		private static final DBConnectionOK INSTANCE = new DBConnectionOK();
	}

	public static DBConnectionOK getConnection() {
		return LazyDBConnection.INSTANCE;
//		if (dbc == null) {
//			dbc = new DBConnectionOK();
//		}
//		return dbc;
	}

}

三、高并发时会出错的延迟初始化方案

使用这种方式,会在高并发时,可能产生不止1个对象,会浪费内存资源

package xyz.jangle.thread.test.nxi_8.lazyinit;

/**
 * 使用这种方式,会在高并发时,可能产生不止1个对象,会浪费内存资源
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年10月29日 下午4:46:46
 * 
 */
public class DBConnectionERROR {

	private DBConnectionERROR() {
		System.out.println(Thread.currentThread().getName() + ": Connection created.");
	}

	private static DBConnectionERROR dbc;

	/**
	 *  使用这种方式,会在高并发时,可能产生不止1个对象,会浪费内存资源
	 * 
	 * @author jangle
	 * @time 2020年10月29日 下午5:00:26
	 * @return
	 */
	public static DBConnectionERROR getConnection() {
		if (dbc == null) {
			dbc = new DBConnectionERROR();
		}
		return dbc;
	}

}

四、模拟并发的任务

使用不同的方案,会有不同的直接结果。

package xyz.jangle.thread.test.nxi_8.lazyinit;

/**
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年10月29日 下午4:51:42
 * 
 */
public class Task implements Runnable {

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + ": 获取连接...");
		var connection = DBConnectionOK.getConnection();
//		var connection = DBConnectionERROR.getConnection();
		System.out.println(Thread.currentThread().getName() + ": 连接获取结束..." + connection);
	}

}

五、执行结果

正确方案的结果:只有一个 Connection created. 出现。

Thread-0: 获取连接...
Thread-3: 获取连接...
Thread-4: 获取连接...
Thread-2: 获取连接...
Thread-1: 获取连接...
Thread-8: 获取连接...
Thread-7: 获取连接...
Thread-9: 获取连接...
Thread-6: 获取连接...
Thread-5: 获取连接...
Thread-12: 获取连接...
Thread-10: 获取连接...
Thread-13: 获取连接...
Thread-14: 获取连接...
Thread-11: 获取连接...
Thread-15: 获取连接...
Thread-16: 获取连接...
Thread-17: 获取连接...
Thread-18: 获取连接...
Thread-0: Connection created.
Thread-3: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-13: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-14: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-20: 获取连接...
Thread-2: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-18: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-4: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-9: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-16: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-15: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-0: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-10: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-28: 获取连接...
Thread-27: 获取连接...
Thread-17: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-11: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-26: 获取连接...
Thread-25: 获取连接...
Thread-26: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-12: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-5: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-1: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-8: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-6: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-24: 获取连接...
Thread-24: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-7: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-20: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-19: 获取连接...
Thread-23: 获取连接...
Thread-21: 获取连接...
Thread-22: 获取连接...
Thread-21: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-23: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-19: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-25: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-27: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-28: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029
Thread-22: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionOK@61e7b029

 高并发存在问题的结果:出现了N++ 个Connection created.  说明增加不必要的内存开销。

Thread-1: 获取连接...
Thread-5: 获取连接...
Thread-7: 获取连接...
Thread-6: 获取连接...
Thread-9: 获取连接...
Thread-4: 获取连接...
Thread-2: 获取连接...
Thread-0: 获取连接...
Thread-3: 获取连接...
Thread-11: 获取连接...
Thread-10: 获取连接...
Thread-8: 获取连接...
Thread-13: 获取连接...
Thread-12: 获取连接...
Thread-14: 获取连接...
Thread-0: Connection created.
Thread-11: Connection created.
Thread-0: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@43b3991a
Thread-12: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@49c2adca
Thread-15: 获取连接...
Thread-9: Connection created.
Thread-14: Connection created.
Thread-4: Connection created.
Thread-2: Connection created.
Thread-1: Connection created.
Thread-24: 获取连接...
Thread-3: Connection created.
Thread-25: 获取连接...
Thread-24: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@212c3c52
Thread-1: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@212c3c52
Thread-27: 获取连接...
Thread-2: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@f265828
Thread-23: 获取连接...
Thread-4: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@50ebff79
Thread-22: 获取连接...
Thread-14: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@4bfd1a
Thread-9: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@40cb18f5
Thread-21: 获取连接...
Thread-15: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@49c2adca
Thread-18: 获取连接...
Thread-19: 获取连接...
Thread-20: 获取连接...
Thread-17: 获取连接...
Thread-10: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@49c2adca
Thread-5: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@49c2adca
Thread-7: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@49c2adca
Thread-6: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@49c2adca
Thread-11: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@49c2adca
Thread-16: 获取连接...
Thread-8: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@43b3991a
Thread-13: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@43b3991a
Thread-16: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-17: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-20: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-19: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-18: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-21: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-22: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-23: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-27: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-28: 获取连接...
Thread-26: 获取连接...
Thread-26: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-25: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-3: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee
Thread-28: 连接获取结束...xyz.jangle.thread.test.nxi_8.lazyinit.DBConnectionERROR@7acaf4ee

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值