1. 程式人生 > >作業系統PV原語練習(1)

作業系統PV原語練習(1)

題目描述:
一條河上架設了由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();
                }
            }
        }
    }
}