利用信号量来实现读写锁

发布于 2月12日  约 9 分钟

前言

为什么要用java来实现?

因为php就是一个残缺的语言!因为对于并发而言,最重要的原子操作。其中并发和阻塞基本上实现都是借助于硬件的实现。而信号量就是基本上每个操作系统都提供的api。

什么是读写锁

其实读写锁分为两种。一个是读优先,一个是写优先。

什么是信号量

信号量最主要的是P操作和V操作。

P操作

semaphore减1。当semaphore小于0时,此时线程阻塞。

V操作

semaphore就会加1。如果小于等于0,唤醒一个等待线程。

实现一个互斥锁。

互斥锁,是在某一个时刻,只有一个线程可以运行。

将semaphore初始值设为1。
当semaphore执行获取锁时,semaphore减1。semaphore为0,当下一个线程想要获取锁时,semaphore再减1。此时semaphore小于0时,线程阻塞。
当释放锁时,semaphore就会加1。并且唤醒一个等待线程。

public class MutexLock {  
    private Semaphore mutex = new Semaphore(1);  
  
    public void lock() throws InterruptedException{  
        mutex.acquire();  
    }  
  
    public void unlock(){  
        mutex.release();  
    }  
}

实现读写锁

实现步骤

  1. 在ReadLock和WriteLock都加上一个写锁。这样保证读操作还是写操作同时只有一个线程可以进行。
  2. 读写锁,是可以允许重复读的。所以添加一个readCound计数。表示当前有多少读线程。因为readCount是共享变量。所以用countMutex进行保护。
  3. 当readCount等于0时,表示第一个读线程。尝试获取锁。如果拿到写锁,readCount++。下一个读线程就不用获取锁。如果没有获取锁,则readCount一直是0。读线程处于等待状态。
  4. 离开时,只有所有的读结束,才释放锁。唤醒一个等待线程。一般是写线程。

具体实现

public class ReadWriteLock {  
  
    private int readCount = 0;  
  
    private MutexLock countMutex = new MutexLock();  
    private MutexLock writeMutex = new MutexLock();  
  
    public class ReadLock{  
  
        public void lock() throws InterruptedException{  
            //readCount是共享变量,所以需要实现一个锁来控制读写  
 //synchronized(ReadWriteLock.class){}  countMutex.lock();  
            //只有是第一个读者,才将写锁加锁。其他的读者都是进行下一步  
            if(readCount == 0){  
                writeMutex.lock();  
            }  
            ++readCount;  
            countMutex.unlock();  
  
        }  
  
        public void unlock() throws InterruptedException{  
            countMutex.lock();  
            readCount--;  
            //只有当读者都读完了,才会进行写操作  
            if(readCount == 0){  
                writeMutex.unlock();  
            }  
            countMutex.unlock();  
        }  
    }  
  
    public class WriteLock{  
  
        public void lock() throws InterruptedException{  
            writeMutex.lock();  
        }  
  
        public void unlock(){  
            writeMutex.unlock();  
        }  
  
  
    }  
}

测试代码

public class Main {  
  
    private static ReadWriteLock readWriteLock = new ReadWriteLock();  
    private static ReadWriteLock.ReadLock readLock = readWriteLock.new ReadLock();  
    private static ReadWriteLock.WriteLock writeLock = readWriteLock.new WriteLock();  
  
    public static void main(String[] args){  
        test();  
    }  
  
    private static void test(){  
        Thread t;  
        int writeNum = (int)(Math.random() * 10);  
        for(int i = 0; i < 10; i++){  
//            if(i == writeNum){  
                if((int)(Math.random() * 10) > 5){  
                t = new Thread(){  
                    public void run(){  
                        try{  
                            writeLock.lock();  
                            System.out.println(this.getName() + " writing");  
                            Thread.sleep(  
                                    (int)(Math.random() * 6 * 1000));  
                            System.out.println(this.getName() + " write done");  
                            writeLock.unlock();  
                        }catch (Exception e){}  
  
                    }  
                };  
  
  
  
            }else{  
                t = new Thread(){  
                    public void run(){  
                        try{  
                            readLock.lock();  
                            System.out.println(this.getName() + " reading");  
                            Thread.sleep(  
                                    (int)(Math.random() * 3 * 1000));  
                            System.out.println(this.getName() + " read done");  
  
                            readLock.unlock();  
                        }catch (Exception e){}  
                    }  
                };  
            }  
  
            t.setName("thread " + i);  
            t.start();  
        }  
    }  
      
}

结果

图片上传不了,就直接贴出来。某一次测试结果如下

thread 2 writing
thread 2 write done
thread 4 writing
thread 4 write done
thread 9 writing
thread 9 write done
thread 0 reading
thread 6 reading
thread 8 reading
thread 7 reading
thread 5 reading
thread 0 read done
thread 6 read done
thread 5 read done
thread 8 read done
thread 7 read done
thread 3 writing
thread 3 write done
thread 1 writing
thread 1 write done
阅读 281发布于 2月12日

推荐阅读
孤岛
用户专栏

心情好,就更新

0 人关注
23 篇文章
专栏主页
目录