多线程-读写锁(1)
多线程读写锁关系
读--读 并行 ,不阻塞
读--写 串行,阻塞
写--写 串行,阻塞
package chapter3; import java.util.Random; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Created by 13 on 2017/5/5. */ public class ReadWriteLockDemo { private static Lock lock = new ReentrantLock(); private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); private static Lock readLock = reentrantReadWriteLock.readLock(); private static Lock writeLock = reentrantReadWriteLock.writeLock(); private int value; public Object handleRead(Lock lock) throws InterruptedException { while(true){//此处添加while循环,确保一直循环读,程序的效果应该每次读都是是18个线程并行读 try { lock.lock(); Thread.sleep(1000);//模拟读操作 System.out.println(Thread.currentThread().getName()+"读操作:" + value); // return value; } finally { lock.unlock(); } } } public void handleWrite(Lock lock, int index) throws InterruptedException { while (true) {//循环写,2个写线程,线程1写的时候线程2等待,也可能线程1一直写,看谁先获得锁。 try { //运行的结果是线程1先获得锁,进行写操作345后释放锁,然后线程2此刻获得锁,进行写操作426,然后释放锁 lock.lock();//线程2后续几次又分别获得写锁,一直写426.接着在线程2释放锁的时候,读锁获得了资源,进行读(18个并行) //读的过程中,不能进行写操作,读写是串行互斥的。 Thread.sleep(1000);//模拟写操作 value = index; System.out.println(Thread.currentThread().getName()+"写操作:" + value); } finally { lock.unlock(); } } } public static void main(String args[]) { final ReadWriteLockDemo demo = new ReadWriteLockDemo(); Runnable readRunnable = new Runnable() { @Override public void run() { //分别使用两种锁来运行,性能差别很直观的就体现出来,使用读写锁后读操作可以并行,节省了大量时间 try { demo.handleRead(readLock); //demo.handleRead(lock); } catch (InterruptedException e) { e.printStackTrace(); } } }; Runnable writeRunnable = new Runnable() { @Override public void run() { //分别使用两种锁来运行,性能差别很直观的就体现出来 try { demo.handleWrite(writeLock, new Random().nextInt(1000)); //demo.handleWrite(lock, new Random().nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } } }; for (int i = 0; i < 18; i++) { new Thread(readRunnable).start();//18个读锁是并行的 } for (int i = 18; i < 20; i++) { new Thread(writeRunnable).start();//两个写锁匙串行的。读与写之间也是串行的 } } }
运行结果如下:
Thread-1读操作:0
Thread-0读操作:0
Thread-8读操作:0
Thread-6读操作:0
Thread-3读操作:0
Thread-7读操作:0
Thread-2读操作:0
Thread-4读操作:0
Thread-5读操作:0
Thread-10读操作:0
Thread-12读操作:0
Thread-11读操作:0
Thread-9读操作:0
Thread-13读操作:0
Thread-16读操作:0
Thread-15读操作:0
Thread-14读操作:0
Thread-17读操作:0 //18次并行读操作
Thread-18写操作:345 //写线程1获得写锁
Thread-19写操作:426 //写线程2获得写锁
Thread-19写操作:426 //写线程2获得写锁
Thread-19写操作:426
Thread-19写操作:426
Thread-19写操作:426
Thread-19写操作:426 //写线程2获得写锁
Thread-0读操作:426 //读线程获得读锁
Thread-4读操作:426
Thread-3读操作:426
Thread-7读操作:426
Thread-17读操作:426
Thread-13读操作:426
Thread-11读操作:426
Thread-1读操作:426
Thread-6读操作:426
Thread-8读操作:426
Thread-2读操作:426
Thread-5读操作:426
Thread-12读操作:426
Thread-10读操作:426
Thread-9读操作:426
Thread-15读操作:426
Thread-16读操作:426
Thread-14读操作:426 //读线程获得读锁
Thread-18写操作:345 //写线程1获得写锁
Thread-18写操作:345
Thread-18写操作:345
Thread-18写操作:345
Thread-18写操作:345