2012-04-10 40 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