我正在用Java编写一个程序来处理Semaphores的任务 . 我对Semaphores和并发的想法还很陌生 . 问题描述如下:
-
布尔的向量V [] . 如果Pi需要使用临界区,则V [i]为"True" .
-
二进制信号量B []的向量,用于阻止进入其临界区的进程:B [i]将是信号量阻塞进程Pi .
-
只要需要唤醒阻塞进程以使用临界区,就会使用特殊的调度程序进程SCHED .
-
SCHED被等待特殊信号量S阻止
-
当进程Pi需要进入临界区时,它将V [i]设置为"True",向信号量S发信号,然后等待信号量B [i] .
-
每当SCHED被解除阻塞时,它选择具有最小索引i的过程Pi,其中V [i]是"True" . 然后通过信令B [i]唤醒过程Pi,并且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();
}
}
}
我相信我的逻辑是正确的,但是我遇到了很多错误(比如线程“Thread-1”中的异常java.lang.NullPointerException) . 任何人都可以解释我做错了什么并给我一些帮助 . 非常感谢!
1 回答
您的
NPE
可能是因为您从未初始化您的信号量数组 - 但如果没有正确的堆栈跟踪很难说 .两条建议:
1)你可能想给你的类变量更有意义的名字:B N S V.想象一下,离开这个项目并在4个月内重新审视它并且必须仔细阅读 .
2)在编写任何代码之前,在白板上找出你的类模型 . 您有一些方法可以使用与某些静态字段同名的信号量 . 程序中对象的关系是什么?如果你不知道,你的程序也不知道 .