阻塞同步:一种悲观并发策略保证共享数据在同一时刻只被一条线程使用,通过使用synchronize和ReentranLock来实现
实现:synchronize关键字经过编译后会在同步块前后生成monitorenter和monitorexit2个字节码指令,这两个字节码会根据一个reference类型的参数来指定要锁定或解锁的对象,如果synchronize没有指明对象,就回根据修饰的是实例方法还是类方法去取对应的对象实例,或者Class对象作为锁对象。
synchronize同步块对同一条线程是可入的,不会把自己锁死,并且会阻塞其它后面的线程,同时阻塞和唤醒其它线程是需要操作系统帮忙的,所以synchronize是一个重量级的操作,应该避免频繁使用。
ReentranLock相比较synchronize实现了等待可中断,公平锁,和对锁绑定多个条件的功能
阻塞同步最大的问题在于线程阻塞和唤醒的性能问题
非阻塞同步:基于冲突检测的乐观并发策略,非阻塞同步在jdk1.5以后出现
实现:使用硬件指令集:比较并交换(Compare-and-Swap简称比较并交换)
CAS指令有3个操作数,为内存地址,旧的预期值,新的值,CAS执行时只有当内存地址符合旧的预期值时才会进行更新
eg:AtomicInteger的incrementAndGet();
线程本地存储:
如果一个变量需要在多个线程共享,可以使用volatile关键字声明是易变的,如果变量要被线程独享,可以通过ThreadLocal类将对象放在TreadLocalMap对象里,key为当前线程的hash值