1、首先要保证并发的正确性,然后在此基础上实现高效。
2、线程安全
1、什么是线程安全?
所谓线程安全是指:当多个线程访问一个对象时,如果不用考虑这些线程在运行环境下的调度和交替执行,也不需要额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象是线程安全的。
2、Java中是如何实现线程安全的?
1、Java语言中将各种操作共享的数据分为以下5类:不可变、绝对线程安全、相对线程安全、线程兼容、和县城对立。
2、Java API中标注自己是绝对线程安全的类绝大多数都是不是绝对线程安的。
3、线程兼容是指对象本身并不是线程安全的,但是可以通过调用端正确的使用同步手段来保证对象在并发环境中可以安全的使用。
4、线程对立是指无论调用端是否采取同步措施,都无法在多线程环境中并发使用的代码。
3、线程安全的实现方法:
1、互斥同步。
互斥同步是指在多个线程并发访问共享数据时,保证共享数据在同一时刻只被一个(或者是一些,使用信号量的时候)线程使用。互斥是实现同步的一种手段。
互斥的实现方式:临界区、互斥量和信号量。在Java中基本的互斥同步手段是synchronized关键字。除了synchronized关键字外,还可以使用java.util.concurrent包中的重入锁ReentrantLock来实现同步。相比synchronized,ReentrantLock增加了一些高级功能:等待可中断、可实现公平锁和可以绑定多个条件。
2、非阻塞同步。
互斥同步最主要的缺点是进行线程阻塞和唤醒所带来的性能问题,所以这种同步也被称为阻塞同步。
这种乐观的并发策略的许多实现都不需要把线程挂起,因此这种同步操作称为非阻塞同步。不过,这个乐观的并发策略需要"操作和冲突检测这两个步骤具有原子性"。 3、无同步方案。
同步只是保证共享数据争用时的正确性的手段,如果一个方法不涉及共享数据,那么他就无需任何同步措施去保证正确性,因此一些代码是天生安全的。
其中的两类代码:可重入代码、线程本地存储(把共享数据的可见范围限制在同一线程之内)。
4、锁优化
1、高效并发是从JDK1.5到JDK1.6的一个重要改进。HotSpot开发团队在这个版本上花费了大量精力去实现各种锁优化技术。如适应性自旋、锁消除、锁粗化、轻量级锁和偏向锁。
2、自旋锁和自适应自旋。
让另一个请求锁的线程不放弃处理器的执行时间,而是“稍等一下”看持有锁的线程会不会很快释放锁。让线程执行一个忙循环(自旋),这就是自旋锁。自旋次数的默认值是10次。
3、锁消除
是指虚拟机即时编译器在运行时,对一些代码上要求同步但是被检测到不可能存在共享数据竞争的锁进行消除。
4、锁粗化
如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至枷锁操作是出现在循环的内部,那即是没有线程竞争,频繁的进行互斥同步操作也会导致不必要性能损耗。虚拟机将会把枷锁同步的范围扩展(粗化)到整个操作序列的外部。
5、轻量级锁
JDK1.6中加入的新型锁机制。