不使用ReentrantReadWriteLock的情况:
public class LockTest {
public static void main(String[] args) {
ReadWrite readWrite = new ReadWrite();
for (int i = 0; i < 5; i++) {
new Thread(() -> readWrite.write(Thread.currentThread().getName(), Thread.currentThread().getName()), String.valueOf(i)).start();
}
for (int i = 0; i < 5; i++) {
new Thread(() -> readWrite.read(Thread.currentThread().getName()), String.valueOf(i)).start();
}
}
}
class ReadWrite {
private volatile Map<String, Object> map = new HashMap<>();
//这里没有ReentrantReadWriteLock
public void write(String k, String v) {
System.out.println(Thread.currentThread().getName() + "开始写");
//睡半秒
try {TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}
map.put(k, v);
System.out.println(Thread.currentThread().getName() + "结束写");
}
public void read(String k) {
System.out.println(Thread.currentThread().getName() + "开始读");
//睡半秒
try {TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}
Object o = map.get(k);
System.out.println(Thread.currentThread().getName() + "结束读" + o);
}
}
运行结果:
ReentrantReadWriteLock的简单应用:
public class LockTest {
public static void main(String[] args) {
ReadWrite readWrite = new ReadWrite();
for (int i = 0; i < 5; i++) {
new Thread(() -> readWrite.write(Thread.currentThread().getName(), Thread.currentThread().getName()), String.valueOf(i)).start();
}
for (int i = 0; i < 5; i++) {
new Thread(() -> readWrite.read(Thread.currentThread().getName()), String.valueOf(i)).start();
}
}
}
class ReadWrite {
private volatile Map<String, Object> map = new HashMap<>();
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void write(String k, String v) {
lock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "开始写");
//睡半秒
try {TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}
map.put(k, v);
System.out.println(Thread.currentThread().getName() + "结束写");
} finally {
lock.writeLock().unlock();
}
}
public void read(String k) {
lock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "开始读");
//睡半秒
try {TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}
Object o = map.get(k);
System.out.println(Thread.currentThread().getName() + "结束读" + o);
} finally {
lock.readLock().unlock();
}
}
}
运行结果:
写操作得排队,读操作可以并发