Java 信号量:具有优先级的关键部分

Java 信号量:具有优先级的关键部分,java,synchronization,semaphore,critical-section,Java,Synchronization,Semaphore,Critical Section,我正在用Java编写一个程序,处理赋值的信号量。对于信号量和并发性的概念,我还是个新手。 问题描述如下: 布尔数的向量V[]。如果Pi需要使用临界截面,则V[i]为“真” 阻止进程进入其关键部分的二进制信号量B[]的向量:B[i]将是信号量阻止进程Pi 当阻塞的进程需要唤醒以使用关键部分时,将使用一个特殊的调度程序进程SCHED SCHED被等待一个特殊的信号量S阻塞 当进程Pi需要进入临界段时,它将V[i]设置为“True”,向信号量S发送信号,然后等待信号量B[i] 每当SCHED被解除阻塞

我正在用Java编写一个程序,处理赋值的信号量。对于信号量和并发性的概念,我还是个新手。 问题描述如下:

  • 布尔数的向量V[]。如果Pi需要使用临界截面,则V[i]为“真”
  • 阻止进程进入其关键部分的二进制信号量B[]的向量:B[i]将是信号量阻止进程Pi
  • 当阻塞的进程需要唤醒以使用关键部分时,将使用一个特殊的调度程序进程SCHED
  • SCHED被等待一个特殊的信号量S阻塞
  • 当进程Pi需要进入临界段时,它将V[i]设置为“True”,向信号量S发送信号,然后等待信号量B[i]
  • 每当SCHED被解除阻塞时,它就会选择具有最小索引i的进程Pi,其中V[i]为“True”。然后,进程Pi通过信令B[i]被唤醒,SCHED通过阻塞信号量S返回睡眠状态
  • 当过程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();
            }
            }
       }
    
    import java.util.concurrent.Semaphore;
    公共类进程扩展线程{
    静态布尔值V[];
    int i;
    静态信号量B[];//阻塞信号量
    静态信号量;
    私有静态int-id;
    静态int N;
    静态int=0;
    公共静态无效进程(int i,int n){
    id=i;
    N=N;
    V=新布尔值[N];
    }
    私有无效延迟(){
    试一试{
    睡眠(随机(500);
    }
    捕捉(中断异常p){
    }
    }
    私有静态int随机(int n){
    return(int)Math.round(n*Math.random()-0.5);
    }
    私有void入口协议(inti){
    V[Process.id]=true;
    整圈=N;
    while(V[Process.id]==true&&turn==N){
    System.out.println(“P”+Process.id+“正在请求关键部分”);
    信号;
    }
    关键(进程id);
    wait(B[Process.id]);
    V[Process.id]=false;
    }
    专用无效等待(信号量S){
    如果(Process.id>0){
    进程id--;
    }否则{
    //将Process.id添加到id.queue和block
    wait(B[Process.id]);
    }
    }
    专用无效信号(信号量S){
    如果(B[Process.id]!=null){
    Sched(Process.id);
    }否则{
    Process.id++;//从队列中删除进程
    临界(Process.id);//唤醒当前进程
    }
    }
    私有无效关键(int i){
    System.out.println(“P”+Process.id+“在关键部分”);
    延迟();
    exitprotocol(i);
    }
    私有无效出口协议(int i){
    System.out.println(“P”+Process.id+“正在离开临界段”);
    V[id]=假;
    信号;
    }
    公共作废附表(int i){
    if(B[Process.id]==null){
    信号(B[Process.id]);
    }
    等候;;
    }
    公开募捐{
    对于(int i=0;i<5;i++){
    附表(i);
    entryprotocol(Process.id);
    试一试{
    wait(Process.id);
    }
    捕捉(中断异常p){
    }
    信号;
    }
    }
    公共静态void main(字符串[]args){
    int N=5;
    工艺p[]=新工艺[N];
    对于(int i=0;i

    我相信我的逻辑是正确的,但我得到了很多错误(比如线程“thread-1”java.lang.NullPointerException中的异常)。有谁能告诉我我做错了什么&给我一些帮助。非常感谢

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

    两条建议:

    1) 您可能希望为类变量指定比以下更有意义的名称: B N s v 想象一下,离开这个项目,在4个月内重新审视它,并且必须通读一遍


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

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

    两条建议:

    1) 您可能希望为类变量指定比以下更有意义的名称: B N s v 想象一下,离开这个项目,在4个月内重新审视它,并且必须通读一遍


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

    很多错误,比如什么?很多nullpointerexception。这实际上是我目前遇到的唯一错误stacktrace通常对在这种情况下发现问题非常有帮助。请更正缩进。“很多错误”,比如什么?很多nullpointerexception。这实际上是我目前唯一的错误。stacktrace通常对在这种情况下发现问题非常有帮助。请更正您的缩进。谢谢您的建议。您是否建议我做其他事情,因为我完全被难住了?您是否尝试初始化信号量数组?将你的堆栈跟踪粘贴到问题中啊啊啊啊,我实际上已经猜出来了。我现在正在处理数组索引超出范围的问题,但感谢bunchthanks的建议。你还有什么建议我做的吗?因为我完全被难住了