1

我正在用 Java 编写一个程序来处理信号量的任务。我对信号量和并发性的想法仍然很陌生。问题描述如下:

  1. 布尔值向量 V[]。如果 Pi 需要使用临界区,则 V[i] 为“真”。
  2. 用于阻止进程进入其临界区的二进制信号量 B[] 向量:B[i] 将是信号量阻塞进程 Pi。
  3. 每当需要唤醒阻塞的进程以使用临界区时,都会使用特殊的调度程序进程 SCHED。
  4. SCHED 因等待特殊信号量 S 而被阻塞
  5. 当进程 Pi 需要进入临界区时,它将 V[i] 设置为“True”,向信号量 S 发出信号,然后等待信号量 B[i]。
  6. 每当 SCHED 被解除阻塞时,它会选择具有最小索引 i 且 V[i] 为“True”的进程 Pi。然后进程 Pi 通过信号 B[i] 被唤醒,并且 SCHED 通过阻塞信号量 S 重新进入睡眠状态。
  7. 当进程 Pi 离开临界区时,它会向 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();
        }
        }
   }

我相信我的逻辑是正确的,但是我遇到了很多错误(例如线程“Thread-1”java.lang.NullPointerException 中的异常)。任何人都可以阐明我做错了什么并为我提供一些帮助。非常感谢!

4

1 回答 1

4

NPE可能是因为您从未初始化信号量数组 - 但如果没有适当的堆栈跟踪,很难说。

两条忠告:

1)您可能希望给您的类变量起比:B N S V 更有意义的名称。想象一下离开这个项目并在 4 个月内重新访问它,并且必须通读它。

2) 在编写任何代码之前,在白板上找出你的类模型。您的方法采用与某些静态字段同名的信号量。你的程序中对象的关系是什么?如果你不知道,很可能你的程序也不知道。

于 2012-04-10T05:10:39.100 回答