利用信號量來實現讀寫鎖

前言

爲何要用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
相關文章
相關標籤/搜索