可变类不是线程安全的。
DateTimeFormater:https://blog.csdn.net/megustas_jjc
代码:
实验:
这个不是线程安全的。
因为内部的成员变量是可变的。
可变的类不加保护就会发生问题的。
---188---
解决办法1:加锁。
转化为线程安全的。
解决办法2: 不可变对象。DataTimeFormater多线程是线程安全得。
---189---
不可变类设计:
---
final修饰数组的时候仅仅是保证引用不能改变,但是不能保证数组是不能改变的。
进行拷贝赋值给新的数组再给value保证不可变性。
---
---190---
保护性拷贝是有修改的话会创建一个新的对象。
final修饰数组的时候仅仅是保证引用不能改变,但是不能保证数组是不能改变的。
如何处理呢?
看下String的类:
String维护的是一个value数组。
传新的字符串会与原始的字符串共用value数组的。
传进来的是char数组呢?
目的是为了不共享,进行保护性拷贝。
看下subString:
---191---
享元模式是改造保护性拷贝模式的。
保护性拷贝创建的对象太多了,我们用享元设计模式去改造的。
看下使用,比如Long对象。
开始就存上了,就是在初始化的时候。
调用:
---
---
享元模式:https://www.cnblogs.com/adamjwh/p/9070107.html
UML图:https://blog.csdn.net/qq_35495763/article/details/80764914
是线程安全的。
add方法,这个是用保护性拷贝保证线程安全的。
这个是保护性拷贝。
插入String是线程安全的:https://www.cnblogs.com/651434092qq/p/11168608.html
为什么应用要保证线程安全
例如:
是因为BigDecimal单个方法是线程安全的,但是并不能保证多个方法组合式线程安全的。
比如取款。
每个是原子的,但是三个组合不是原子的。
三个组合要用原子类进行保护的。
---192---
享元模式实现连接池:
实现自己的连接池:
---193---
分析:如果不是线程安全的会怎么样呢?
这个是不对的,不是原子操作的。
这两个线程都会从0改为1的。
只能一个线程原子成功,一个线程是失败的。
借连接和归还连接
---194---
测试:
总结:就是一个连接的集合和一个状态的集合,用状态集合去判断连接是不是占用的。
---195---
为什么cas结合wait实际上去掉wait也是可以的。
获取连接为什么cas加wait?
cas适用于短时间 线程少的,不加wait就会不断的while空转的。wait放弃cpu的占用。
改进:
---196---
final的原理:
final在赋值之后会加入写屏障的。
写屏障的作用:不能排序到后面 写屏障之前会同步到主存。
不加final在堆 加final在栈 超了在常量池
---197---
无状态:
---198---