2012-04-10 123 views
1

我正在寫一個程序在Java中處理信號量的任務。對於信號量和併發的想法我還是一個新手。 問題描述如下:信號量:關鍵部分與優先

  1. 布爾值的向量V []。如果Pi需要使用臨界區,則V [i]爲「真」。
  2. 二進制信號量向量B []阻止進程進入其臨界區:B [i]將是信號量阻塞進程Pi。
  3. 只要需要喚醒已禁止的進程以使用關鍵部分,就會使用特殊的調度程序進程SCHED。
  4. SCHED通過等待特殊信號而被阻塞S
  5. 當進程Pi需要進入臨界區時,它將V [i]設置爲「真」,向信號量S發信號,然後等待信號量B [一世]。
  6. 每當SCHED解鎖時,它選擇V [i]爲「True」的索引i最小的進程Pi。工序Pi然後通過信令B [i]和SCHED通過阻斷在信號量S.
  7. 當一個進程裨離開臨界部驚醒回到休眠,它發信號S.

這是我的代碼:

import java.util.concurrent.Semaphore; 

public class Process extends Thread { 
    static boolean V[]; 
    int i; 
    static Semaphore B[]; //blocking semaphore 
    static Semaphore S; 
    private static int id; 
    static int N; 
    static int insist = 0; 

    public static void process (int i, int n) { 
     id = i; 
     N = n; 
     V = new boolean[N]; 
    } 

    private void delay() { 
     try { 
     sleep (random(500)); 
     } 
     catch (InterruptedException p) { 
     } 
    } 

    private static int random(int n) { 
     return (int) Math.round(n * Math.random() - 0.5); 
    } 

    private void entryprotocol(int i) { 
     V[Process.id] = true; 
     int turn = N; 
     while (V[Process.id] == true && turn == N) { 
      System.out.println("P" + Process.id + " is requesting critical section"); 
      signal(S); 
     } 
     critical(Process.id); 
     wait(B[Process.id]); 
     V[Process.id] = false; 
     } 



    private void wait(Semaphore S) { 
     if (Process.id > 0) { 
     Process.id--; 
     } else { 
     //add Process.id to id.queue and block 
     wait(B[Process.id]); 
     } 
    } 

    private void signal(Semaphore S) { 
     if (B[Process.id] != null) { 
      Sched(Process.id); 
     } else { 
      Process.id++; //remove process from queue 
      critical(Process.id); //wakes up current process 
     } 
    } 

    private void critical(int i) { 
     System.out.println("P" + Process.id + " is in the critical section"); 
     delay(); 
     exitprotocol(i); 
    } 

    private void exitprotocol(int i) { 
     System.out.println("P" + Process.id + " is leaving the critical section"); 
     V[id] = false; 
     signal(S); 
    } 

    public void Sched(int i) { 
     if (B[Process.id] == null) { 
     signal(B[Process.id]); 
     } 
     wait(S); 
    } 

    public void run() { 
     for (int i = 0; i < 5; i++) { 
      Sched(i); 
      entryprotocol(Process.id); 
      try { 
       wait(Process.id); 
      } 
      catch (InterruptedException p) { 
      } 
      signal(S); 
     } 
     } 


    public static void main (String[] args) { 
     int N = 5; 

     Process p[] = new Process[N]; 

     for (int i = 0; i < N; i++) { 
     p[i] = new Process(); 
     p[i].start(); 
     } 
     } 
    } 

我相信我在這裏的邏輯是正確的,但我得到了很多的錯誤(如線「線程1」顯示java.lang.NullPointerException除外)。任何人都可以告訴我我做錯了什麼&爲我提供了一些幫助。非常感謝!

+3

'很多錯誤',如什麼? – EJP 2012-04-10 04:37:49

+0

很多nullpointerexception。這實際上是我目前遇到的唯一錯誤 – NuNu 2012-04-10 04:43:05

+0

在這種情況下,stacktrace通常對找到問題非常有幫助。 – trutheality 2012-04-10 04:45:11

回答

4

你的NPE可能是由於你永遠不會初始化你的Semaphore數組 - 但是很難說沒有適當的堆棧跟蹤。

兩個建議件:

1)你可能想給你的類變量更有意義的名稱比: 乙 ň 小號 五 想象一下這個項目4個月走開,並重新審視它並不得不通讀。

2)在編寫任何代碼之前,在白板上找出你的班級模型。你有一些方法將信號與一些靜態字段同名。程序中的對象有什麼關係?如果你不知道,賠率是你的程序不知道。

+0

。有什麼你建議我做,因爲我完全難倒 – NuNu 2012-04-10 06:05:19

+0

你嘗試初始化信號量數組?將你的堆棧跟蹤粘貼到問題 – 2012-04-10 06:45:43

+0

ahhhh我想出了它的實際內容。我正在處理數組索引超出界限,但感謝一堆 – NuNu 2012-04-10 07:14:43