爲何要用java來實現?php
由於php就是一個殘缺的語言!由於對於併發而言,最重要的原子操做。其中併發和阻塞基本上實現都是藉助於硬件的實現。而信號量就是基本上每一個操做系統都提供的api。java
其實讀寫鎖分爲兩種。一個是讀優先,一個是寫優先。api
信號量最主要的是P操做和V操做。併發
semaphore減1。當semaphore小於0時,此時線程阻塞。dom
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(); } }
實現步驟操作系統
具體實現線程
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