“我发现了一个漏洞,你这个转账虽然看起来很美,没有加锁,但是和原来的是有区别的,原来多线程思路是会把旺财和小强的账户同时锁住,然后转账,在这个过程中,别人是不能操作这两个账号的! 而你的Actor方案中,当转账管家给旺财发消息扣款的时候,小强其实是自由的,如果这时候小强的账户被冻结,那你的转账管家还得回滚旺财的扣款,这多麻烦啊。”
Bill:“哈哈,你小子还挺机灵的嘛,看出了这个问题,Actor模型非常适用于多个组件独立工作,相互之间仅仅依靠消息传递的情况。如果想在多个组件之间维持一致的状态(比如咱们例子中的转账),那就不爽了。”
“那怎么解决这个问题?”
“那必须得用一些特殊手段了,有些实现Actor的框架,例如Akka,专门提供了像Coordinated /Transactor这样的机制来处理这个问题。有空的话给你仔细讲讲。”
将数组中的不用的元素设置为null,尽早垃圾回收
缓存可以使用WeakHashMap.及时将key进行回收。
使用定时器将缓存中不用的项目删除或者LinkedHashMap.removeEldestEntry()
1 | import com.alibaba.druid.support.json.JSONUtils; |
输出:1
2{"beijing":"haid","beijing2":"haid2","beijing3":"haid3"}
{"beijing2":"haid2","beijing3":"haid3","beijing4":"haid4"}
将监听器回调及时的清除,可以使用WeakHashMap.
使用内存Heap Profiler进行对象分析。
引用:https://www.cnblogs.com/AlanLee/p/6122416.html
避免使用
new String("zzz")
创建对象,避免创建对象优先使用基本类型.避免装箱引起的内存消耗.
尽量用静态工厂,例如Boolean.valueOf() Integer.valueOf();hashmap.keySet() 因为构造器会创建对象,会消耗内存空间。
- 共有方法返回实例,灵活性高,可以修改api,例如按照线程返回实例
- private 构造方法 防止继承
- 初始化校验.
参考:http://www.importnew.com/6605.html
Builder会增加个类代码,这也意味着开发者在给类增加属性时有时会忘记给该属性添加支持的builder。为了克服这个问题,通常我会将builder嵌套到类中,这样可以很容易地发现哪个相关的builder需要更新
构建对象时,如果碰到类有很多参数——其中很多参数类型相同而且很多参数可以为空时,我更喜欢Builder模式来完成。当参数数量不多、类型不同而且都是必须出现时,通过增加代码实现Builder往往无法体现它的优势。在这种情况下,理想的方法是调用传统的构造函数。再者,如果不需要保持不变,那么就使用无参构造函数调用相应的set方法吧。
必要参数写到构造器里
如果要实现builder的重用性,可以讲初始化工作放到目标类中。不需要重用的话,可以讲初始化工作在builde创建出来的时候,就将实例创建出来。
将构造器 设置为Private并且要抛出异常,就可以解决这个问题.
1 | public class UtilsClass { |
Java 反射是Java中非常重要的特性,各大框架(hibernate\spring\mybatis)都会依赖于反射.
架构师分类与怎样成为架构师?
应用架构师责任范围在哪里?
架构师的工作内容
最近刚刚画的,大家可以个意见吧?
转载自: https://mp.weixin.qq.com/s/f23I1kyJQoNPu6Ntrx0S6g
读后感:
Java1.6
为Synchronized做了优化,增加了从偏向锁到轻量级锁再到重量级锁的过度,但是在最终转变为重量级锁之后,性能仍然较低. 这其中用到了CAS机制。
CAS优点
- Synchronized属于悲观锁,悲观地认为程序中的并发情况严重,所以严防死守。CAS属于乐观锁,乐观地认为程序中的并发情况不那么严重,所以让线程不断去尝试更新。
- 避免了context switch
CAS缺点
- CPU消耗较大,不适合高并发场景(因为冲突太多,失败率高)。
- ABA问题
- 不能保证代码块的原子性。例如不能保证多个变量同时更新.
乐观锁转悲观锁的经典代码见:ConcurrentHashMap的size方法
1 | public int size() { |