一、synchronized:它是java中的一个关键字,它能够把任意一个非NULL的对象看成锁。java
1)做用于方法时,锁住的是对象的实例(this);缓存
2)看成用于静态方法时,锁住的是Class实例,又由于Class的相关数据存储在永久带PermGen(jdk1.8则是metaspace),永久带是全局共享的,所以静态方法锁至关于类的一个全局锁,会锁全部调用该方法的线程;并发
3)synchronized做用于一个对象实例时,锁住的是全部以该对象为锁的代码块。性能
二、Lock:Lock有一个实现类:ReentrantLock,它实现了Lock里面的方法,可是使用Lock的时候必须注意它不会像synchronized执行完成以后或者抛出异常以后自动释放锁,而是须要你主动释放锁,因此咱们必须在使用Lock的时候加上try{}catch{}finally{}块,而且在finally中释放占用的锁资源。this
Lock和synchronized最大的区别就是当使用synchronized,一个线程抢占到锁资源,其余线程必须等待;而使用Lock,一个线程抢占到锁资源,其余的线程能够不等待或者设置等待时间,实在抢不到能够去作其余的业务逻辑。spa
三、ReadWriteLock(读读共享,其余全互斥):它能够实现读写锁,当读取的时候线程会得到read锁,其余线程也能够得到read锁同时并发的去读取,可是写程序运行获取到write锁的时候,其余线程是不能进行操做的,由于write是排它锁,而上面介绍的两种无论你是read仍是write没有抢到锁的线程都会被阻塞或者中断,它也是个接口,里面定义了两种方法readLock()和readLock(),他的一个实现类是ReentrantReadWriteLock。线程
关于读写锁的一个缓存例子CacheDemo:code
package resource.java.ordinary.mul.thread; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 一个缓存demo,读写锁例子,实现读和写互斥、写和写互斥,但有能够多个并发的读,可提升系统性能 * * @author xiao */ public class CacheDemo { // 数据 private Map<String, Object> cache = new HashMap<>(); // 读写锁 private ReadWriteLock rwl = new ReentrantReadWriteLock(); public Object getData(String key) { // 上读锁,多个读时能够并发,不会形成对数据的破坏 rwl.readLock().lock(); Object value = null; try { value = cache.get(key); // 若是数据为空 if (value == null) { // 释放读锁上写锁,上写锁后,数据不能被读 rwl.readLock().unlock(); rwl.writeLock().lock(); try { // 此处判断是为防止多个线程同时进入到这里时,多个线程对数据进行重复写 if (value == null) { // 若是没有数据,则去查DB获取数据 value = "XXX"; } } finally { // 读取数据后释放写锁 rwl.writeLock().unlock(); } // 获取完数据后,恢复读锁,从新读取数据 rwl.readLock().lock(); } } finally { // 从新读取数据释放读锁 value = cache.get(key); rwl.readLock().unlock(); } return value; } }