读写锁简介
介绍:
读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。
在读写锁保持期间也是抢占失效的。
如果读写锁当前没有读者,也没有写者,那么写者可以立刻获得读写锁,否则它必须自旋在那里,直到没有任何写者或读者。
如果读写锁没有写者,那么读者可以立即获得该读写锁,否则读者必须自旋在那里,直到写者释放该读写锁。
并发线程下,所有线程都执行读的操作 不会有问题
并发线程下,部分读部分写会不会有问题 会发生写冲突
并发线程下,所有线程都执行写会不会有问题 会发生写冲突
示例:
public class ReadWriteLock { //创建一个集合 static Map<String,String> map=new HashMap<String,String>(); //创建一个读写锁 static ReentrantReadWriteLock lock=new ReentrantReadWriteLock(); //获取读锁 static Lock readLock=lock.readLock(); //获取写锁 static Lock writeLock=lock.writeLock(); //写操作 public Object put(String key,String value){ writeLock.lock(); try { System.out.println("Write正在执行写操作~"); Thread.sleep(100); String put = map.put(key, value); System.out.println("Write写操作执行完毕~"); return put; } catch (InterruptedException e) { e.printStackTrace(); }finally { writeLock.unlock(); } return null; } //写操作 public Object get(String key){ readLock.lock(); try { System.out.println("Read正在执行读操作~"); Thread.sleep(100); String value = map.get(key); System.out.println("Read读操作执行完毕~"); return value; } catch (InterruptedException e) { e.printStackTrace(); }finally { readLock.unlock(); } return null; } public static void main(String[] args) { ReadWriteLock lock=new ReadWriteLock(); for (int i = 0; i < 10; i++) { int finalI = i; new Thread(()->{ try { //写操作 lock.put(finalI +"","value"+finalI); //读操作 System.out.println(lock.get(finalI+"")); } catch (Exception e) { e.printStackTrace(); } }).start(); } } }
总结:
读锁是共享的
写锁是排他的
互斥原则:
- 读-读能共存,
- 读-写不能共存,
- 写-写不能共存。