读写锁ReentrantReadWriteLock实例

当需要对集合同时进行写入和读取操作时,如果多线程同时操作会出现异常,那么现在利用ReadWriteLock显示锁,可以在写入量比较小,读取量比较大的场景中,方便的实现上述功能。

import java.util.Calendar;

import java.util.Map;

import java.util.TreeMap;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantReadWriteLock;



/**

 * 可重入读写锁

 */

@SuppressWarnings("all")

public class ReadWriteLockDemo {

    private ReentrantReadWriteLock lock = null;

    // 读锁

    private Lock readLock = null;

    // 写锁

    private Lock writeLock = null;

    public int key = 100;

    public int index = 100;

    // 线程共享数据

    public Map<Integer, String> dataMap = null;



    public ReadWriteLockDemo() {

        // 创建公平的可重入读写锁

        lock = new ReentrantReadWriteLock(true);

        readLock = lock.readLock();

        writeLock = lock.writeLock();

        dataMap = new TreeMap<Integer, String>();

    }



    public static void main(String[] args) {

        ReadWriteLockDemo test = new ReadWriteLockDemo();

        // 第一次获取写入锁

        test.writeLock.lock();

        System.out.println("线程" + Thread.currentThread().getName() + "第一次获取写入锁");

        // 第二次获取写入锁(这就是可重入的含义)

        test.writeLock.lock();

        System.out.println("线程" + Thread.currentThread().getName() + "第二次获取写入锁");



        test.readLock.lock();

        System.out.println("线程" + Thread.currentThread().getName() + "第一次获取读取锁");



        test.readLock.lock();

        System.out.println("线程" + Thread.currentThread().getName() + "第二次获取读取锁");



        test.readLock.lock();

        System.out.println("线程" + Thread.currentThread().getName() + "第三次获取读取锁");



        test.writeLock.unlock();

        test.writeLock.unlock();

        test.readLock.unlock();

        test.readLock.unlock();

        test.readLock.unlock();



        test.test();



    }



    public void test() {

        for (int i = 0; i < 10; i++) {

            new Thread(new reader(this)).start();

        }

        for (int i = 0; i < 3; i++) {

            new Thread(new writer(this)).start();

        }

    }



    public void read() {

        readLock.lock();

        try {

            if (dataMap.isEmpty()) {

                Calendar now = Calendar.getInstance();

                System.out.println("线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "读取数据,但是dataMap为空");

            }

            String value = dataMap.get(index);

            Calendar now = Calendar.getInstance();

            System.out.println("线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "读取数据,key=" + index + ",value=" + value + ",dataMap大小为" + dataMap.size());

            if (value != null) {

                index++;

            }

        } finally {

            readLock.unlock();

        }

        try {

            Thread.sleep(3000);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }



    public void write() {

        writeLock.lock();

        try {

            String value = "value" + key;

            dataMap.put(new Integer(key), value);

            Calendar now = Calendar.getInstance();

            System.out.println("线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "写入数据,key=" + key + ",value=" + value + ",dataMap大小为" + dataMap.size());

            key++;

            try {

                Thread.sleep(500);

            } catch (Exception e) {

                e.printStackTrace();

            }

        } finally {

            writeLock.unlock();

        }

    }



    class reader implements Runnable {

        private ReadWriteLockDemo test = null;



        public reader(ReadWriteLockDemo test) {

            this.test = test;

        }



        @Override

        public void run() {

            Calendar now = Calendar.getInstance();

            System.out.println("读取线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "开始执行");

            for (int i = 0; i < 10; i++) {

                test.read();

            }

        }

    }



    class writer implements Runnable {

        private ReadWriteLockDemo test = null;



        public writer(ReadWriteLockDemo test) {

            this.test = test;

        }



        @Override

        public void run() {

            Calendar now = Calendar.getInstance();

            System.out.println("写入线程" + Thread.currentThread().getName() + "在" + now.getTime().getTime() + "开始执行");

            for (int i = 0; i < 10; i++) {

                test.write();

            }

        }

    }

}

 

运行结果: 

线程main第一次获取写入锁

线程main第二次获取写入锁

线程main第一次获取读取锁

线程main第二次获取读取锁

线程main第三次获取读取锁

读取线程Thread-1在1339663449057开始执行

读取线程Thread-7在1339663449057开始执行

读取线程Thread-9在1339663449057开始执行

写入线程Thread-10在1339663449057开始执行

读取线程Thread-3在1339663449057开始执行

读取线程Thread-5在1339663449057开始执行

读取线程Thread-6在1339663449057开始执行

写入线程Thread-12在1339663449057开始执行

线程Thread-9在1339663449057读取数据,但是dataMap为空

读取线程Thread-0在1339663449057开始执行

写入线程Thread-11在1339663449057开始执行

读取线程Thread-2在1339663449057开始执行

线程Thread-7在1339663449057读取数据,但是dataMap为空

线程Thread-1在1339663449057读取数据,但是dataMap为空

读取线程Thread-8在1339663449057开始执行

读取线程Thread-4在1339663449057开始执行

线程Thread-7在1339663449072读取数据,key=100,value=null,dataMap大小为0

线程Thread-1在1339663449072读取数据,key=100,value=null,dataMap大小为0

线程Thread-9在1339663449072读取数据,key=100,value=null,dataMap大小为0

线程Thread-10在1339663449072写入数据,key=100,value=value100,dataMap大小为1

线程Thread-3在1339663449572读取数据,key=100,value=value100,dataMap大小为1

线程Thread-6在1339663449572读取数据,key=100,value=value100,dataMap大小为1

线程Thread-5在1339663449572读取数据,key=100,value=value100,dataMap大小为1

线程Thread-12在1339663449572写入数据,key=101,value=value101,dataMap大小为2

线程Thread-0在1339663450072读取数据,key=103,value=null,dataMap大小为2

线程Thread-11在1339663450072写入数据,key=102,value=value102,dataMap大小为3

线程Thread-2在1339663450572读取数据,key=103,value=null,dataMap大小为3

线程Thread-4在1339663450572读取数据,key=103,value=null,dataMap大小为3

线程Thread-8在1339663450572读取数据,key=103,value=null,dataMap大小为3

线程Thread-10在1339663450572写入数据,key=103,value=value103,dataMap大小为4

线程Thread-12在1339663451072写入数据,key=104,value=value104,dataMap大小为5

线程Thread-11在1339663451572写入数据,key=105,value=value105,dataMap大小为6

线程Thread-10在1339663452072写入数据,key=106,value=value106,dataMap大小为7

线程Thread-12在1339663452572写入数据,key=107,value=value107,dataMap大小为8

线程Thread-9在1339663453071读取数据,key=103,value=value103,dataMap大小为8

线程Thread-11在1339663453071写入数据,key=108,value=value108,dataMap大小为9

线程Thread-7在1339663453571读取数据,key=104,value=value104,dataMap大小为9

线程Thread-6在1339663453571读取数据,key=104,value=value104,dataMap大小为9

线程Thread-1在1339663453571读取数据,key=104,value=value104,dataMap大小为9

线程Thread-5在1339663453571读取数据,key=106,value=value105,dataMap大小为9

线程Thread-3在1339663453571读取数据,key=105,value=value104,dataMap大小为9

线程Thread-10在1339663453571写入数据,key=109,value=value109,dataMap大小为10

线程Thread-0在1339663454071读取数据,key=109,value=value109,dataMap大小为10

线程Thread-12在1339663454071写入数据,key=110,value=value110,dataMap大小为11

线程Thread-2在1339663454571读取数据,key=110,value=value110,dataMap大小为11

线程Thread-8在1339663454571读取数据,key=110,value=value110,dataMap大小为11

线程Thread-4在1339663454571读取数据,key=111,value=value110,dataMap大小为11

线程Thread-11在1339663454571写入数据,key=111,value=value111,dataMap大小为12

线程Thread-10在1339663455071写入数据,key=112,value=value112,dataMap大小为13

线程Thread-12在1339663455571写入数据,key=113,value=value113,dataMap大小为14

线程Thread-11在1339663456071写入数据,key=114,value=value114,dataMap大小为15

线程Thread-10在1339663456571写入数据,key=115,value=value115,dataMap大小为16

线程Thread-9在1339663457071读取数据,key=113,value=value113,dataMap大小为16

线程Thread-12在1339663457071写入数据,key=116,value=value116,dataMap大小为17

线程Thread-3在1339663457571读取数据,key=114,value=value114,dataMap大小为17

线程Thread-11在1339663457571写入数据,key=117,value=value117,dataMap大小为18

线程Thread-6在1339663458071读取数据,key=115,value=value115,dataMap大小为18

线程Thread-7在1339663458071读取数据,key=115,value=value115,dataMap大小为18

线程Thread-5在1339663458071读取数据,key=116,value=value115,dataMap大小为18

线程Thread-0在1339663458071读取数据,key=117,value=value116,dataMap大小为18

线程Thread-1在1339663458071读取数据,key=117,value=value116,dataMap大小为18

线程Thread-10在1339663458071写入数据,key=118,value=value118,dataMap大小为19

线程Thread-8在1339663458571读取数据,key=120,value=null,dataMap大小为19

线程Thread-12在1339663458571写入数据,key=119,value=value119,dataMap大小为20

线程Thread-2在1339663459070读取数据,key=120,value=null,dataMap大小为20

线程Thread-4在1339663459070读取数据,key=120,value=null,dataMap大小为20

线程Thread-11在1339663459070写入数据,key=120,value=value120,dataMap大小为21

线程Thread-10在1339663459570写入数据,key=121,value=value121,dataMap大小为22

线程Thread-12在1339663460070写入数据,key=122,value=value122,dataMap大小为23

线程Thread-11在1339663460570写入数据,key=123,value=value123,dataMap大小为24

线程Thread-9在1339663461070读取数据,key=120,value=value120,dataMap大小为24

线程Thread-10在1339663461070写入数据,key=124,value=value124,dataMap大小为25

线程Thread-12在1339663461570写入数据,key=125,value=value125,dataMap大小为26

线程Thread-3在1339663462070读取数据,key=121,value=value121,dataMap大小为26

线程Thread-7在1339663462070读取数据,key=121,value=value121,dataMap大小为26

线程Thread-1在1339663462070读取数据,key=122,value=value122,dataMap大小为26

线程Thread-6在1339663462070读取数据,key=121,value=value121,dataMap大小为26

线程Thread-0在1339663462070读取数据,key=122,value=value121,dataMap大小为26

线程Thread-5在1339663462070读取数据,key=122,value=value121,dataMap大小为26

线程Thread-11在1339663462070写入数据,key=126,value=value126,dataMap大小为27

线程Thread-8在1339663462570读取数据,key=127,value=null,dataMap大小为27

线程Thread-10在1339663462570写入数据,key=127,value=value127,dataMap大小为28

线程Thread-2在1339663463070读取数据,key=127,value=value127,dataMap大小为28

线程Thread-4在1339663463070读取数据,key=127,value=value127,dataMap大小为28

线程Thread-12在1339663463070写入数据,key=128,value=value128,dataMap大小为29

线程Thread-11在1339663463570写入数据,key=129,value=value129,dataMap大小为30

线程Thread-9在1339663464070读取数据,key=129,value=value129,dataMap大小为30

线程Thread-0在1339663465069读取数据,key=130,value=null,dataMap大小为30

线程Thread-1在1339663465069读取数据,key=130,value=null,dataMap大小为30

线程Thread-7在1339663465069读取数据,key=130,value=null,dataMap大小为30

线程Thread-5在1339663465069读取数据,key=130,value=null,dataMap大小为30

线程Thread-3在1339663465069读取数据,key=130,value=null,dataMap大小为30

线程Thread-6在1339663465069读取数据,key=130,value=null,dataMap大小为30

线程Thread-8在1339663465569读取数据,key=130,value=null,dataMap大小为30

线程Thread-4在1339663466069读取数据,key=130,value=null,dataMap大小为30

线程Thread-2在1339663466069读取数据,key=130,value=null,dataMap大小为30

线程Thread-9在1339663467069读取数据,key=130,value=null,dataMap大小为30

线程Thread-7在1339663468069读取数据,key=130,value=null,dataMap大小为30

线程Thread-3在1339663468069读取数据,key=130,value=null,dataMap大小为30

线程Thread-1在1339663468069读取数据,key=130,value=null,dataMap大小为30

线程Thread-0在1339663468069读取数据,key=130,value=null,dataMap大小为30

线程Thread-6在1339663468069读取数据,key=130,value=null,dataMap大小为30

线程Thread-5在1339663468069读取数据,key=130,value=null,dataMap大小为30

线程Thread-8在1339663468569读取数据,key=130,value=null,dataMap大小为30

线程Thread-4在1339663469069读取数据,key=130,value=null,dataMap大小为30

线程Thread-2在1339663469069读取数据,key=130,value=null,dataMap大小为30

线程Thread-9在1339663470069读取数据,key=130,value=null,dataMap大小为30

线程Thread-0在1339663471068读取数据,key=130,value=null,dataMap大小为30

线程Thread-1在1339663471068读取数据,key=130,value=null,dataMap大小为30

线程Thread-3在1339663471068读取数据,key=130,value=null,dataMap大小为30

线程Thread-7在1339663471068读取数据,key=130,value=null,dataMap大小为30

线程Thread-6在1339663471068读取数据,key=130,value=null,dataMap大小为30

线程Thread-5在1339663471068读取数据,key=130,value=null,dataMap大小为30

线程Thread-8在1339663471568读取数据,key=130,value=null,dataMap大小为30

线程Thread-2在1339663472068读取数据,key=130,value=null,dataMap大小为30

线程Thread-4在1339663472068读取数据,key=130,value=null,dataMap大小为30

线程Thread-9在1339663473068读取数据,key=130,value=null,dataMap大小为30

线程Thread-0在1339663474068读取数据,key=130,value=null,dataMap大小为30

线程Thread-1在1339663474068读取数据,key=130,value=null,dataMap大小为30

线程Thread-3在1339663474068读取数据,key=130,value=null,dataMap大小为30

线程Thread-6在1339663474068读取数据,key=130,value=null,dataMap大小为30

线程Thread-5在1339663474068读取数据,key=130,value=null,dataMap大小为30

线程Thread-7在1339663474068读取数据,key=130,value=null,dataMap大小为30

线程Thread-8在1339663474568读取数据,key=130,value=null,dataMap大小为30

线程Thread-2在1339663475068读取数据,key=130,value=null,dataMap大小为30

线程Thread-4在1339663475068读取数据,key=130,value=null,dataMap大小为30

线程Thread-9在1339663476067读取数据,key=130,value=null,dataMap大小为30

线程Thread-6在1339663477067读取数据,key=130,value=null,dataMap大小为30

线程Thread-7在1339663477067读取数据,key=130,value=null,dataMap大小为30

线程Thread-0在1339663477067读取数据,key=130,value=null,dataMap大小为30

线程Thread-1在1339663477067读取数据,key=130,value=null,dataMap大小为30

线程Thread-3在1339663477067读取数据,key=130,value=null,dataMap大小为30

线程Thread-5在1339663477067读取数据,key=130,value=null,dataMap大小为30

线程Thread-8在1339663477567读取数据,key=130,value=null,dataMap大小为30

线程Thread-2在1339663478067读取数据,key=130,value=null,dataMap大小为30

线程Thread-4在1339663478067读取数据,key=130,value=null,dataMap大小为30

线程Thread-9在1339663479067读取数据,key=130,value=null,dataMap大小为30

线程Thread-0在1339663480067读取数据,key=130,value=null,dataMap大小为30

线程Thread-5在1339663480067读取数据,key=130,value=null,dataMap大小为30

线程Thread-1在1339663480067读取数据,key=130,value=null,dataMap大小为30

线程Thread-3在1339663480067读取数据,key=130,value=null,dataMap大小为30

线程Thread-6在1339663480067读取数据,key=130,value=null,dataMap大小为30

线程Thread-7在1339663480067读取数据,key=130,value=null,dataMap大小为30

线程Thread-8在1339663480567读取数据,key=130,value=null,dataMap大小为30

线程Thread-4在1339663481067读取数据,key=130,value=null,dataMap大小为30

线程Thread-2在1339663481067读取数据,key=130,value=null,dataMap大小为30

 

 

你可能感兴趣的:(读写锁ReentrantReadWriteLock实例)