正确使用Object.wait和Object.notify

1. 前言

现在的代码实现里面几乎不用Object.wait和Object.notify了,但是对其进行学习还是有助于理解为啥他们被Locksupport.park和unpark替换了。

2. 使用汇总

关于完整使用,参考文章:如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

文章中使用wait的生产者和消费者例子可以看看。

主要要点是:

对需要线程间互斥的对象用synchronized,持有其监视器锁

永远在循环(loop)里调用 wait 和 notify, 主要避免条件不满足是就被虚假唤醒,......

JAVA代码优化记录

1. 避免伪共享(false sharing)

1.1 概述

代码层面放的比较近的字段频繁一起并发变更可能导致需要写相同的cache line,写cache line根据MESI协议,要让别的cpu下对应的cache line保持禁写。这导致原本可以从L1 L2cache中获取的数据不得不从L3或者内存中获取,命中率大大降低,性能下降。

参考资料:http://ifeve.com/from-javaeye-false-sharing/

1.2 解决办法

避免伪共享的关键就是避免并发访问的数据在一个cache line。那么解决办法也比较简单了,需要避免伪共享的对象,加个......

JAVA后端问题定位和排错

1. 介绍

原本打算自己总结一下的。但是觉得人家总结的很好,我这里就不浪费笔墨了,给大家推荐一下文章即可。

linux后端诊断与调试技术

PPT-JVM问题定位和排错

下面我对文章中可以重点关注的一些点做一下强调。大家看的时候可以留意下。

2. 查找JAVA进程中消耗CPU最多的线程

这个问题大家可能经常碰到。传统的做法是:

top命令找出有问题Java进程及线程id:

a. 开启线程显示模式(shift+h)

b. 按CPU使用率排序(shift+p,如果按照内存排就shift+m)

c. 记下Java进程id及其CPU高的线程id

......

第11章:序列化

74. 谨慎地实现Serializable接口

实现序列化接口带来的问题:

灵活性:实现序列化接口会导致程序发布后灵活性变差(导出后要永远支持这种序列化形式)。

安全性和BUG:增加了BUG和安全漏洞的可能性:反序列化机制是一个“隐蔽的构造器”。依靠默认的反序列化机制,很容易使对象的约束关系遭到破坏,以及遭到非法访问

测试负担:随着类发型新的版本,相关的测试负担也增加了。

最佳实践:为了继承而设计的类,应尽可能少地去实现序列化接口。

75. 考虑使用自定义序列化形式

76. 保护性地编写readObeject方法

针对74条中的安全性问题,可以使用readO......

第10章:并发

这一章还是比较简单。因为之前看过并发编程实战这本书的内容。如果需要完整了解并发,还是需要看下那本书。

66. 同步访问共享的可变数据

67. 避免过度同步

在同步区域内做尽量少的工作。例如调用外星方法以及引用可变对象都会造成线程不安全。

68. executor和task优先于线程

自己去通过Thread编写多线程任务是不太好的,因为要考虑很多细节。采用并发包中的ExecutorService来管理线程任务是最佳实践

69. 并发工具优先于wait和notify

并发操作,都优先使用并发包里面的工具和数据结构。

70. 线程安全性的文档化

提供一些线程......