Java Code之线程与同步(二)

接Java Code之线程与同步(一)的例子,使用synchronized来挂锁。实际上这个锁的效率并不高,分析一下,如果门外排队的都是读数据的人,那么这些人是可以同时进入屋子里的,他们不会影响数据的配对。也就是说可以多个读数据操作同时进行,写数据操作只能同时有一个,并且在写数据时,不能读数据。

Java中就有一个这样的挂锁机制,看代码:

如之前的例子,只需修改FileManager.java

package com.iteye.badpie.javacode.thread.sync;

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

public class FileManager {

    private Random mRandom;
    private String mName = "默认名字";
    private String mEmail = "默认电子邮件";
    private Lock mReadLock;
    private Lock mWriteLock;

    public FileManager() {
        mRandom = new Random();

        // 构建读写锁
        ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
        mReadLock = rwLock.readLock();
        mWriteLock = rwLock.writeLock();
    }

    public void write(String id, String name, String email) {
        // 写锁
        mWriteLock.lock();
        mName = name;
        try {
            Thread.sleep(getRandomInt());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mEmail = email;
        System.out.println(String.format("写数据 id:%s, name:%s, email:%s", id, name, email));
        // 解写锁
        mWriteLock.unlock();
    }

    public void read(String id) {
        // 读锁
        mReadLock.lock();
        try {
            Thread.sleep(getRandomInt());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(String.format("读数据 id:%s, name:%s, email:%s", id, mName, mEmail));
        // 解读锁
        mReadLock.unlock();
    }

    private int getRandomInt() {
        return mRandom.nextInt(2000);
    }

}

再次运行,结果如下:

主线程开始运行
主线程运行结束
读数据 id:r, name:默认名字, email:默认电子邮件
写数据 id:w, name:0的名字, email:0的电子邮件
读数据 id:r, name:0的名字, email:0的电子邮件
写数据 id:w, name:1的名字, email:1的电子邮件
读数据 id:r, name:1的名字, email:1的电子邮件
写数据 id:w, name:2的名字, email:2的电子邮件
读数据 id:r, name:2的名字, email:2的电子邮件
写数据 id:w, name:3的名字, email:3的电子邮件
写数据 id:w, name:4的名字, email:4的电子邮件
读数据 id:r, name:4的名字, email:4的电子邮件

很明显,区分了读和写的锁,线程的调度更加均匀,效率更高了。

 

你可能感兴趣的:(java,thread,线程,同步,读写锁)