1. 程式人生 > 其它 >Java JUC併發之讀寫鎖

Java JUC併發之讀寫鎖

九、讀寫鎖 ReadWriteLock

Read Lock 讀鎖 (共享鎖)=> 允許多個執行緒一起讀 讀的時候不允許寫操作

Write Lock 寫鎖 (獨佔鎖)=> 只允許一個執行緒(獨家)寫的時候不允許讀操作

讀寫鎖的目的: 保證執行緒安全 讀寫分離

package com.liu.rw;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 獨佔鎖(排他鎖) 寫鎖 一次只能被一個執行緒佔有
 * 共享鎖 讀鎖 多個執行緒同時佔有
 * ReadWriteLock 讀寫鎖
 * 讀-讀 可以共存!
 * 讀-寫 不能共存 讀寫分離
 * 寫-寫 不能共存
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCacheLock myCache = new MyCacheLock();

        // 寫入操作
        for (int i = 1; i <= 10; i++) {
            final String temp = String.valueOf(i);

            new Thread(()->{
                myCache.put(temp,temp);
            },String.valueOf(i)).start();
        }


        // 讀取操作
        for (int i = 1; i <= 10; i++) {
            final String temp = String.valueOf(i);

            new Thread(()->{
                myCache.get(temp);
            },String.valueOf(i)).start();
        }


    }
}

/**
 * 自定義快取 get set 使用Map
 */
class MyCache{

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

    // 存 寫
    public void put(String key, Object value) {
        System.out.println(Thread.currentThread().getName() + "寫入");
        map.put(key, value);
        System.out.println(Thread.currentThread().getName() + "寫入完畢!");

    }

    // 讀 取
    public void get(String key) {

        System.out.println(Thread.currentThread().getName() + "讀取");
        Object o = map.get(key);
        System.out.println(Thread.currentThread().getName() + "讀取完畢!");

    }
}

class MyCacheLock{

    private volatile Map<String, Object> map = new HashMap<>();
    // 讀寫鎖 更加細粒度的操作
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

   // private ReentrantLock lock = new ReentrantLock(); // 一般的可重入鎖

    // 存 寫
    // 寫入的時候,只希望同時只有一個執行緒寫
    public void put(String key, Object value) {

        readWriteLock.writeLock().lock(); // 加一個讀寫鎖的寫鎖

        try {
            System.out.println(Thread.currentThread().getName() + "寫入");
            map.put(key, value);
            System.out.println(Thread.currentThread().getName() + "寫入完畢!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock(); // 解鎖
        }

    }

    // 讀 取   加讀鎖的的目的:防止產生髒資料(寫入的時候有讀操作)
    // 所有人都可以讀
    public void get(String key) {

        readWriteLock.readLock().lock(); // 加 讀鎖

        try {

            System.out.println(Thread.currentThread().getName() + "讀取");
            Object o = map.get(key);
            System.out.println(Thread.currentThread().getName() + "讀取完畢!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock(); // 解鎖
        }

    }
}

本文來自部落格園,作者:{夕立君},轉載請註明原文連結:https://www.cnblogs.com/liuzhhhao/p/15016479.html