java锁:第四章:读写锁

理论:

未使用读写锁的代码:html

package com.javaliao.backstage;

import java.util.HashMap;
import java.util.Map;

class Data{
    private volatile Map map = new HashMap<String,Object>();

    //写
    public void put(String key,Object value){
        System.out.println(Thread.currentThread().getName()+"\t 正在写入:"+key);
        try {
            Thread.sleep(300);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"\t 写入完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    //读
    public void get(String key){
        System.out.println(Thread.currentThread().getName()+"\t 正在读取");
        try {
            Thread.sleep(300);
            Object value = map.get(key);
            System.out.println(Thread.currentThread().getName()+"\t 读取完成:"+value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Demo {

    public static void main(String[] args) {
        Data data = new Data();
        //五个写的线程
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(()->{
                data.put(tempInt+"",tempInt+"");
            },String.valueOf(i)).start();
        }
        //五个读的线程
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(()->{
                data.get(tempInt+"");
            },String.valueOf(i)).start();
        }
    }
}

控制台:java

能够看到写的操做原子性和独占性没有获得保证,0线程正在写入共享资源的时候,其余线程有写入和读取的共享资源操做,致使数据不一致。并发

是否能够添加Lock锁解决原子性和独占性的问题?

不能够,由于添加线程

private Lock lock = new ReentrantLock();

只能保证一个线程读,不能让多个线程同时读取,不符合实际需求。code

使用ReentrantReadWriteLock解决原子性和独占性,能够很好的解决并发性和数据的一致性

读写锁的代码:htm

package com.javaliao.backstage;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

class Data{
    private volatile Map map = new HashMap<String,Object>();
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    public void put(String key,Object value){
        //写锁
        lock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"\t 正在写入:"+key);
            Thread.sleep(300);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"\t 写入完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.writeLock().unlock();
        }
    }

    public void get(String key){
        //读锁
        lock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"\t 正在读取");
            Thread.sleep(300);
            Object value = map.get(key);
            System.out.println(Thread.currentThread().getName()+"\t 读取完成:"+value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.readLock().unlock();
        }
    }
}


public class Demo {

    public static void main(String[] args) {
        Data data = new Data();
        //五个写的线程
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(()->{
                data.put(tempInt+"",tempInt+"");
            },String.valueOf(i)).start();
        }
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(()->{
                data.get(tempInt+"");
            },String.valueOf(i)).start();
        }
    }
}

控制台:blog

比较:资源