Java多线程下ReadWriteLock(读写锁)的使用

  1. 声明读写锁:private ReadWriteLock lock = new ReentrantReadWriteLock();
  2. 独占锁:lock.writeLock()
  3. 共享锁:lock.readLock()



一:无锁案例

在自定义类NoLockTest中存在一个数据变量map,类中存在一个读方法get和写方法put,则在多线程情况下,数据操作会出现错误。


	public class RW {
	    public static void main(String[] args) {
	        NoLockTest my = new NoLockTest();
	
	        //存
	        for (int i = 1; i <=10 ; i++) {
	            final Integer number = i;
	            new Thread(()->{
	                my.put(number+"",number+"");
	            },"Thread"+String.valueOf(i)).start();
	        }
	
	        //取
	        for (int i = 1; i <=10 ; i++) {
	            final Integer number = i;
	            new Thread(()->{
	                my.get(number+"");
	            },"Thread"+String.valueOf(i)).start();
	        }
	
	
	    }
	
	}
	
	//无锁
	class NoLockTest{
	    private volatile Map<String,String> map = new HashMap<>();
	
	    //存
	    public  void put(String key,String value){
	        System.out.println(Thread.currentThread().getName()+"写入"+key);
	        map.put(key,value);
	        System.out.println(Thread.currentThread().getName()+"写入完毕");
	    }
	
	    //取
	    public void get(String key){
	        System.out.println(Thread.currentThread().getName()+"读取"+key);
	        String value = map.get(key);
	        System.out.println(Thread.currentThread().getName()+"读取完毕");
	    }
	
	}


结果:

Java多线程下ReadWriteLock(读写锁)的使用_第1张图片线程2在写入的时候被插队了,因此就导致线程2还没有写完就被线程1强行写进来了,这样做很明显不符合逻辑。



二:有锁案例

这里的锁并没有使用一般的Lock中的可重入锁,因为Lock锁虽然也能实现线程的有序进行,但lock会将内容直接就给单线程锁死了,可这里针对于map变量的操作情况是:在put数据的时候需要加锁使其有序进行;在get数据的时候无序强调有序进行,因为get操作只牵扯到数据的读取,数据本身不会被改变,因此允许多线程操作反而会有更高的效率。


public class RW {
    public static void main(String[] args) {
        LockTest my = new LockTest();

        //存
        for (int i = 1; i <=10 ; i++) {
            final Integer number = i;
            new Thread(()->{
                my.put(number+"",number+"");
            },"Thread"+String.valueOf(i)).start();
        }

        //取
        for (int i = 1; i <=10 ; i++) {
            final Integer number = i;
            new Thread(()->{
                my.get(number+"");
            },"Thread"+String.valueOf(i)).start();
        }


    }

}




//加锁
class LockTest{
    private volatile Map<String,String> map = new HashMap<>();
    //读写锁
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    //存,一次只允许一个线程操作
    public  void put(String key,String value){
        lock.writeLock().lock();//独占锁
        try {
            System.out.println(Thread.currentThread().getName()+"写入"+key);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"写入完毕");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();//解锁
        }
    }

    //取,一次可允许多个线程操作
    public void get(String key){
        lock.readLock().lock();//共享锁
        try {
            System.out.println(Thread.currentThread().getName()+"读取"+key);
            String value = map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取完毕");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();//释放锁
        }

    }

}

Java多线程下ReadWriteLock(读写锁)的使用_第2张图片Java多线程下ReadWriteLock(读写锁)的使用_第3张图片

你可能感兴趣的:(java相关)