基于线程安全的一些原则来编程当然可以避免并发问题,但不是所有人都能写出高质量的线程安全的代码,并且如果代码里到处都是线程安全的控制也极大地影响了代码可读性和可维护性。因此,Java平台为了解决这个问题,提供了很多线程安全的类和并发工具,通过这些类和工具就能更简便地写线程安全的代码。归纳一下有以下几种:
- 同步容器类
- 并发容器类
- 生产者和消费者模式
- 阻塞和可中断方法
- Synchronizer
这些类和方法的使用都可以从JDK DOC查到,但在具体使用中还是有很多问题需要注意
同步容器类
同步容器类就是一些经过同步处理了的容器类,比如List有Vector,Map有Hashtable,查看其源码发现其保证线程安全的方式就是把每个对外暴露的存取方法用synchronized关键字同步化,这样做我们立马会想到有以下问题:
1)性能有问题
同步化了所有存取方法,就表明所有对这个容器对象的操作将会串行,这样做来得倒是干净,但性能的代价也是很可观的
2)复合操作问题
同步容器类只是同步了单一操作,如果客户端是一组复合操作,它就没法同步了,依然需要客户端做额外同步,比如以下代码:
getLast和deleteLast都是复合操作,由先前对原子性的分析可以判断,这依然存在线程安全问题,有可能会抛出ArrayIndexOutOfBoundsException的异常,错误产生的逻辑如下所示:
解决办法就是通过对这些复合操作加锁
<