读写过程的互斥锁

读写进程的互斥锁

以下的代码完成了对某个资源的读写互斥锁,具体说明如下:
1. 若正有若干进程在读资源,新的读进程可以共享资源;
1. 若正有若干进程在读资源,一条写进程想要独占资源,则写进程等待,到所有读进程全部完成之后控制资源;
2. 若正有一个进程在独占写资源,则所有其他进程等待,到这个进程完成之后,其他进程共享或独占资源。

 

换句话说就是,独占的进程必须等到所有共享进程完成操作之后才能执行;共享的进程也必须等到独占进程释放资源之后才能共享。

 

/**
 * <pre>
 * 文件名称:Lock.java
 * 文件描述:读写锁
 * 创建日期:2009-2-19
 * </pre>
 * 
 * @version 1.0
 */
package cn.sh.huang.util;

/**
 * <pre>
 * 类型名称:Lock
 * 类型目的:读写锁,在某个或某些进程读数据的时候,屏蔽写操作,在某单独进程写数据的时候,屏蔽其它的读、写操作。
 * 使用说明:
 *     for (Lock lock = lock.read(); lock != null; lock.done()) {
 *         ... // 在此方法体内的所有语句均被只读保护,在最后一个读进程完成之前,不允许写操作
 *     }
 *     
 *     for (Lock lock = lock.write(); lock != null; lock.done()) {
 *         ... // 此方法体内的所有语句均被只写保护,仅有一个进程能够执行,期间不允许其它进程的读写访问
 *     }
 * </pre>
 */
public final class Lock
{
    private static final int LOCK_READ = 1, LOCK_WRITE = 2;

    private static Bolt reader = new Bolt(), writer = new Bolt();

    private final int flag; // 0: UNKNOWN; 1: Reading...; 2: Writing... 

    private Lock(int flag)
    {
        this.flag = flag;
    }

    
    /**
     * <pre>
     * 方法说明:只读访问,可以多个进程并发读
     * </pre>
     *
     * @return 返回当前的只读锁,在解锁的时候需要
     */
    public static Lock read()
    {
        synchronized (writer) {
            while (writer.exists())
                try {
                    writer.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            synchronized (reader) {
                reader.inc();
            }
        }
        return new Lock(LOCK_READ);
    }

    /**
     * <pre>
     * 方法说明:只写访问,只允许一个进程操作
     * </pre>
     *
     * @return 返回当前的锁,以备解锁时候用
     */
    public static Lock write()
    {
        synchronized (writer) { // 检查是否有写者
            while (writer.exists())
                try {
                    writer.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            writer.inc();
        }
        synchronized (reader) {
            while (reader.exists())
                // 检查是否有读者
                try {
                    reader.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            return new Lock(LOCK_WRITE);
        }
    }

    public Lock done() {
        if (flag == LOCK_READ) return readDone();
        else return writeDone(); // obviously
    }
    /**
     * <pre>
     * 方法说明:完成读操作,解锁
     * </pre>
     *
     * @return 返回null,表明完成解锁
     */
    private Lock readDone()
    {
        synchronized (reader) {
            reader.dec();
            reader.notifyAll();
        }
        return null;
    }

    /**
     * <pre>
     * 方法说明:完成写操作,解锁
     * </pre>
     *
     * @return 返回null,表明完成解锁
     */
    private Lock writeDone()
    {
        synchronized (writer) {
            writer.dec();
            writer.notifyAll();
        }
        return null;
    }

    static class Bolt
    {
        private int count = 0;

        public boolean exists()
        {
            return count != 0;
        }

        public void inc()
        {
            count++;
        }

        public void dec()
        {
            count--;
        }
    }
}

 

1 楼 云中苍月 2009-03-16  
建议楼主学习一下JDK1.5的ReentrantReadWriteLock
2 楼 regular 2009-03-17  
ReentrantReadWriteLock
云中苍月 写道

建议楼主学习一下JDK1.5的ReentrantReadWriteLock

Sorry, 我的项目开发目前还没办法升级到Java 5。因此才自力更生。
不过我会看一下上面提到的锁的源代码,看看是否与我的设计有差异。