Java多线程工具包java.util.concurrent---ReadWriteLock

Posted yvan1115

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程工具包java.util.concurrent---ReadWriteLock相关的知识,希望对你有一定的参考价值。

什么是ReadWriteLock

java.util.concurrent.locks.ReadWriteLock 读写锁是一种先进的线程锁机制。它能够允许多个线程在同一时间对某特定资源进行读取,但同一时间内只能有一个线程对其进行写入。
读写锁的理念在于多个线程能够对一个共享资源进行读取,而不会导致并发问题。并发问题的发生场景在于对一个共享资源的读和写操作的同时进行,或者多个写操作并发进行。

ReadWriteLock 锁规则

  • 读锁:如果没有任何写操作线程锁定 ReadWriteLock,并且没有任何写操作线程要求一个写锁(但还没有获得该锁)。因此,可以有多个读操作线程对该锁进行锁定。
  • 写锁:如果没有任何读操作或者写操作。因此,在写操作的时候,只能有一个线程对该锁进行锁定。

示例

package com.yvan.readWriteLock;

import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
 * 读写锁ReadWriteLock
 * @author yvan
 *
 */
public class AppMain 

    public static void main(String[] args) 
        ReadWriteLock lock = new ReentrantReadWriteLock();
        ConcurrentHashMap<String, String> data = new ConcurrentHashMap<String, String>();
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        for (int i = 0; i < 3; i++) 
            executorService.execute(new Read(lock, data));
            executorService.execute(new Write(lock, data));
        
        executorService.shutdown();
    


class Read implements Runnable 

    private ReadWriteLock lock;
    private ConcurrentHashMap<String, String> data;

    public Read(ReadWriteLock lock, ConcurrentHashMap<String, String> data) 
        this.lock = lock;
        this.data = data;
    

    @Override
    public void run() 
        try 
            // 读锁可以让多个线程同时拥有
            lock.readLock().lock();
            System.out.println(Thread.currentThread().getName() + "读取数据:");
            TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 1000));
            StringBuffer sb = new StringBuffer();
            for (Entry<String, String> item : data.entrySet()) 
                sb.append(item.getKey() + "---" + item.getValue());
            
            sb.append("读取完毕");
            System.out.println(sb.toString()+"\\r\\n");

         catch (Exception e) 
            e.printStackTrace();
         finally 
            lock.readLock().unlock();
        

    



class Write implements Runnable 

    private ReadWriteLock lock;
    private ConcurrentHashMap<String, String> data;

    public Write(ReadWriteLock lock, ConcurrentHashMap<String, String> data) 
        this.lock = lock;
        this.data = data;
    

    @Override
    public void run() 
        try 
            // 写锁只能让一个线程拥有
            lock.writeLock().lock();
            System.out.print(Thread.currentThread().getName()+"准备写入数据...");
            TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 1000));
            data.put(Thread.currentThread().getName()+"-write", Thread.currentThread().getName()+"-content");
            System.out.println(Thread.currentThread().getName()+"写入数据完毕\\r\\n");
         catch (Exception e) 
            e.printStackTrace();
         finally 
            lock.writeLock().unlock();
        

    


某一次的执行结果

pool-1-thread-1读取数据: 读取完毕

pool-1-thread-2准备写入数据…pool-1-thread-2写入数据完毕

pool-1-thread-4准备写入数据…pool-1-thread-4写入数据完毕

pool-1-thread-3读取数据:
pool-1-thread-5读取数据:

pool-1-thread-4-write—pool-1-thread-4-contentpool-1-thread-2-write—pool-1-thread-2-content读取完毕

pool-1-thread-4-write—pool-1-thread-4-contentpool-1-thread-2-write—pool-1-thread-2-content读取完毕

pool-1-thread-6准备写入数据…pool-1-thread-6写入数据完毕

可以看到红色标注的打印结果,说明同时有两个线程拥有读锁,而写锁每次只允许一个线程拥有,直到该线程解锁

以上是关于Java多线程工具包java.util.concurrent---ReadWriteLock的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程工具包java.util.concurrent---CyclicBarrier

Java多线程工具包java.util.concurrent---ExecutorService

Java多线程工具包java.util.concurrent---ReadWriteLock

Java多线程工具包java.util.concurrent---Lock

Java多线程_同步工具CyclicBarrier

Java多线程(线程池原子性并发工具类)