并发编程——不可变类

本文探讨了并发编程中不可变类的重要性,以日期转换问题为例揭示了SimpleDateFormat的线程安全问题,并介绍了如何通过使用不可变类如DateTimeFormatter确保线程安全。此外,文章详细阐述了String类的不可变性,通过保护性拷贝确保内部数据不被改变。还讨论了享元模式在减少内存消耗中的应用,如Integer的缓存以及自定义连接池的实现。最后,文章提到了无状态对象在保证线程安全方面的角色,建议在设计Servlet时避免设置成员变量。
摘要由CSDN通过智能技术生成

目录

一、日期转换问题

解决

二、不可变类String 

final的特点

保护性拷贝

三、享元模式

体现 

享元模式之自定义连接池

四、无状态 


一、日期转换问题

一般使用的最多的是SimpleDateFormat,但是因为是不可变类,在多个线程操作共享变量的时候内部的数据会改变,造成线程安全问题,接下来看一下测试案例。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
     for (int i = 0; i < 10; i++) {//运行10个线程
           new Thread(() -> {
            try {
                log.debug("{}", sdf.parse("1951-04-21"));
                 } catch (Exception e) {
                        log.error("{}", e);
                 }
                 }).start();
        }

  有很大几率出现 java.lang.NumberFormatException 或者出现不正确的日期解析结果 

17:27:19.884 a.ThreadTest15 [Thread-5] - {}
java.lang.NumberFormatException: For input string: ""
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Long.parseLong(Long.java:601)
	at java.lang.Long.parseLong(Long.java:631)
	at java.text.DigitList.getLong(DigitList.java:195)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2084)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at ThreadTest15.lambda$main$0(ThreadTest15.java:16)
	at java.lang.Thread.run(Thread.java:748)
17:27:19.885 a.ThreadTest15 [Thread-0] - {}
java.lang.NumberFormatException: empty String
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at ThreadTest15.lambda$main$0(ThreadTest15.java:16)
	at java.lang.Thread.run(Thread.java:748)
17:27:19.884 a.ThreadTest15 [Thread-3] - {}
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at ThreadTest15.lambda$main$0(ThreadTest15.java:16)
	at java.lang.Thread.run(Thread.java:748)
17:27:19.885 a.ThreadTest15 [Thread-4] - {}
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值