返回顶部

收藏

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

标签:java,并发,ReentrantReadWriteLock

收藏

0人收藏

支持

0

反对

0

发表评论