java多线程 -- ReadWriteLock 读写锁
写一条线程,读多条线程能够提升效率。
写写/读写 需要“互斥”;
读读 不需要互斥.
- ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。
- ReadWriteLock 读取操作通常不会改变共享资源,但执行写入操作时,必须独占方式来获取锁。对于读取操作占多数的数据结构。 ReadWriteLock 能提供比独占锁更高的并发性。而对于只读的数据结构,其中包含的不变性可以完全不需要考虑加锁操作。
api相关方法:
- Lock readLock()返回用于读取操作的锁。
- Lock writeLock()返回用于写入操作的锁。
demo:
package com.company; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /* * 1. ReadWriteLock : 读写锁 * * 写写/读写 需要“互斥” * 读读 不需要互斥 * */ public class TestReadWriteLock { public static void main(String[] args) { ReadWriteLockDemo rw = new ReadWriteLockDemo(); new Thread(() -> rw.set(new ReadWriteLockDemo.Person("soyoungboy", 27)), "Write:").start(); for (int i = 0; i < 10; i++) { new Thread(() -> rw.get()).start(); } } } class ReadWriteLockDemo { private Person person; private ReadWriteLock lock = new ReentrantReadWriteLock(); //读 void get() { lock.readLock().lock(); //上锁 try { if (person != null) { System.out.println(Thread.currentThread().getName() + " ==> person : " + person.toString()); }else { System.out.println(Thread.currentThread().getName() + ""); } } finally { lock.readLock().unlock(); //释放锁 } } //写 void set(Person person) { lock.writeLock().lock(); try { System.out.println(Thread.currentThread().getName()); this.person = person; } finally { lock.writeLock().unlock(); } } static class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } } }
结果:
Thread-0 Thread-1 Thread-3 Thread-2 Write: Thread-4 ==> person : Person{name='soyoungboy', age=27} Thread-6 ==> person : Person{name='soyoungboy', age=27} Thread-8 ==> person : Person{name='soyoungboy', age=27} Thread-5 ==> person : Person{name='soyoungboy', age=27} Thread-7 ==> person : Person{name='soyoungboy', age=27} Thread-9 ==> person : Person{name='soyoungboy', age=27}