作業系統PV原語練習(1)
阿新 • • 發佈:2018-12-20
題目描述: 一條河上架設了由N個橋墩組成的一座橋。若一個橋墩只能站一個人,過河的人只能沿著橋向前走而不能向後退。 過河時,只要對岸無人過,就可以過。 但不允許河對岸的兩個人同時過,以防止出現死鎖。 請給出兩個方向的人順利過河的同步演算法。 (可以簡單擴充為多個方向上一個環形的橋 實現簡單的給兩個方向)
思路如下: 第一個上橋的人獲取橋的互斥訊號量,最後一個上橋的人釋放橋的互斥訊號量 對於一個方向設立一個計數器,同時設立該計數器的互斥訊號量 還有一個訊號量是限制橋上最多的人數
程式碼如下:
package ConcurrentControl; import java.util.Random; import java.util.concurrent.Semaphore; /** 題目描述: 一條河上架設了由N個橋墩組成的一座橋。若一個橋墩只能站一個人,過河的人只能沿著橋向前走而不能向後退。 過河時,只要對岸無人過,就可以過。 但不允許河對岸的兩個人同時過,以防止出現死鎖。 請給出兩個方向的人順利過河的同步演算法。 (可以簡單擴充為多個方向上一個環形的橋 實現簡單的給兩個方向) 思路如下: 第一個上橋的人獲取橋的互斥訊號量,最後一個上橋的人釋放橋的互斥訊號量 對於一個方向設立一個計數器,同時設立該計數器的互斥訊號量 還有一個訊號量是限制橋上最多的人數 */ public class Problem_04 { public static void main(String argv[]){ test(); } public static void test(){ Random random = new Random(2);//指定種子數字 for(int i=0; i<20; i++){ int randNum = random.nextInt(); boolean isPositive = true; if(randNum>0) isPositive = false; new Thread(new Passer(isPositive)).start(); } } private static class Container{ // 獲取橋的互斥訊號量 public static Semaphore bridgeMutex = new Semaphore(1); // 限制橋上人數的訊號量 public static Semaphore numOfPasserOnBridge = new Semaphore(3); // 正方向的計數器 public static int cntPositive = 0; // 正方向計數器互斥訊號量 public static Semaphore cntPositiveMutex = new Semaphore(1); // 負方向的計數器 public static int cntNegative = 0; // 負方向計數器互斥訊號量 public static Semaphore cntNegativeMutex = new Semaphore(1); } private static class Passer implements Runnable{ boolean isPositive = true; Passer(boolean isPositive){ this.isPositive = isPositive; } private void cross(){ System.out.printf(Thread.currentThread().getName()+" -> "+this.isPositive+"\n"); } @Override public void run() { if(isPositive){ // 判斷是否第一個上橋 try { Container.cntPositiveMutex.acquire(); Container.cntPositive++; if(Container.cntPositive==1){ System.out.printf("********************\n"); Container.bridgeMutex.acquire(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { Container.cntPositiveMutex.release(); } // 執行cross操作 try { Container.numOfPasserOnBridge.acquire(); cross(); } catch (InterruptedException e) { e.printStackTrace(); } finally { Container.numOfPasserOnBridge.release(); } // 判斷是否最後一個人離開橋 try { Container.cntPositiveMutex.acquire(); Container.cntPositive--; if(Container.cntPositive==0){ Container.bridgeMutex.release(); System.out.printf("********************\n"); } } catch (InterruptedException e) { e.printStackTrace(); } finally { Container.cntPositiveMutex.release(); } } else{ // 判斷是否第一個上橋 try { Container.cntNegativeMutex.acquire(); Container.cntNegative++; if(Container.cntNegative==1){ System.out.printf("********************\n"); Container.bridgeMutex.acquire(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { Container.cntNegativeMutex.release(); } // 執行cross操作 try { Container.numOfPasserOnBridge.acquire(); cross(); } catch (InterruptedException e) { e.printStackTrace(); } finally { Container.numOfPasserOnBridge.release(); } // 判斷是否最後一個人離開橋 try { Container.cntNegativeMutex.acquire(); Container.cntNegative--; if(Container.cntNegative==0){ Container.bridgeMutex.release(); System.out.printf("********************\n"); } } catch (InterruptedException e) { e.printStackTrace(); } finally { Container.cntNegativeMutex.release(); } } } } }