利用信号量来实现读写锁

前言

为何要用java来实现?php

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

什么是读写锁

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

什么是信号量

信号量最主要的是P操做和V操做。并发

P操做

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

V操做

semaphore就会加1。若是小于等于0,唤醒一个等待线程。测试

实现一个互斥锁。

互斥锁,是在某一个时刻,只有一个线程能够运行。ui

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

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
相关文章
相关标签/搜索