ReentrantReadWriteLock

package com.yonge.lock;

import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 需求:多线程操作同一数据,可以多线程同时读数据,只能一个线程修改数据;
 * @author wb-gaoy
 * @version $Id: ShareData.java,v 0.1 2011-12-31 下午3:00:09 wb-gaoy Exp $
 */
public class ShareData {

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    private String                 data;

    public ShareData(String data) {
        this.data = data;
    }

    /**
     * 修改数据的方法
     * @param str
     */
    public void merge(String str) {
        lock.writeLock().lock();
        System.out.println("ThreadName:" + Thread.currentThread().getName() + "-"
                           + Thread.currentThread().getId() + "    locking...");
        try {
            data = str;
            System.out.println("ThreadName:" + Thread.currentThread().getName() + "-"
                               + Thread.currentThread().getId() + "   修改为:" + str);
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("ThreadName:" + Thread.currentThread().getName() + "-"
                               + Thread.currentThread().getId() + "    unlock...");
            lock.writeLock().unlock();
        }
    }

    /**
     * 获取数据的方法
     */
    public String get() {
        lock.readLock().lock();
        System.out.println("ThreadName:" + Thread.currentThread().getName() + "-"
                           + Thread.currentThread().getId() + "    locking...");
        try {
            System.out.println("ThreadName:" + Thread.currentThread().getName() + "-"
                               + Thread.currentThread().getId() + "   获取为:" + data);
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
            System.out.println("ThreadName:" + Thread.currentThread().getName() + "-"
                               + Thread.currentThread().getId() + "    unlock...");
        }
        return data;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {

        final ShareData shareData = new ShareData("Hello,World!!");

        for (int i = 0; i < 50; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    shareData.get();
                }
            }, "A").start();

            new Thread(new Runnable() {

                @Override
                public void run() {
                    shareData.merge(new Random().nextLong() + "");
                }
            }, "B").start();

        }
    }

    /**
     * 总结:
     *      1、readLock在没有被释放的时候可以被多个线程同时读取,此时还可以重入writeLock锁
     *      2、writeLock在没有被释放的时候其他锁不能进入,也不能重入readLock锁,直到writeLock被解锁
     */
}