Is my code in a state of deadlock? - java

On compiling my code below it seems to be in a state of deadlock, and i don't know how i can fix it. I am attempting to write a pipeline as a sequence of threads linked together as a buffer, and each thread can read the preceding node in the pipeline, and consequentially write to the next one. The overall goal is to spilt a randomly generated arraylist of data over 10 threads and sort it.
class Buffer{
// x is the current node
private int x;
private boolean item;
private Lock lock = new ReentrantLock();
private Condition full = lock.newCondition();
private Condition empty = lock.newCondition();
public Buffer(){item = false;}
public int read(){
lock.lock();
try{
while(!item)
try{full.await();}
catch(InterruptedException e){}
item = false;
empty.signal();
return x;
}finally{lock.unlock();}
}
public void write(int k){
lock.lock();
try{
while(item)
try{empty.await();}
catch(InterruptedException e){}
x = k; item = true;
full.signal();
}finally{lock.unlock();}
}
}
class Pipeline extends Thread {
private Buffer b;
//private Sorted s;
private ArrayList<Integer> pipe; // array pipeline
private int ub; // upper bounds
private int lb; // lower bounds
public Pipeline(Buffer bf, ArrayList<Integer> p, int u, int l) {
pipe = p;ub = u;lb = l;b = bf;//s = ss;
}
public void run() {
while(lb < ub) {
if(b.read() > pipe.get(lb+1)) {
b.write(pipe.get(lb+1));
}
lb++;
}
if(lb == ub) {
// store sorted array segment
Collections.sort(pipe);
new Sorted(pipe, this.lb, this.ub);
}
}
}
class Sorted {
private volatile ArrayList<Integer> shared;
private int ub;
private int lb;
public Sorted(ArrayList<Integer> s, int u, int l) {
ub = u;lb = l;shared = s;
// merge data to array from given bounds
}
}
class Test1 {
public static void main(String[] args) {
int N = 1000000;
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0;i<N;i++) {
int k = (int)(Math.random()*N);
list.add(k);
}
// write to buffer
Buffer b = new Buffer();
b.write(list.get(0));
//Sorted s = new Sorted();
int maxBuffer = 10;
int index[] = new int[maxBuffer+1];
Thread workers[] = new Pipeline[maxBuffer];
// Distribute data evenly over threads
for(int i=0;i<maxBuffer;i++)
index[i] = (i*N) / maxBuffer;
for(int i=0;i<maxBuffer;i++) {
// create instacen of pipeline
workers[i] = new Pipeline(b,list,index[i],index[i+1]);
workers[i].start();
}
// join threads
try {
for(int i=0;i<maxBuffer;i++) {
workers[i].join();
}
} catch(InterruptedException e) {}
boolean sorted = true;
System.out.println();
for(int i=0;i<list.size()-1;i++) {
if(list.get(i) > list.get(i+1)) {
sorted = false;
}
}
System.out.println(sorted);
}
}

When you start the run methods, all threads will block until the first thread hits full.await(). then one after the other, all threads will end up hitting full.await(). they will wait for this signal.
However the only place where full.signal occurs is after one of the read methods finishes.
As this code is never reached (because the signal is never fired) you end up with all threads waiting.
in short, only after 1 read finishes, will the writes trigger.
if you reverse the logic, you start empty, you write to the buffer (with signal, etc, etc) and then the threads try to read, I expect it will work.
generally speaking you want to write to a pipeline before reading from it. (or there's nothing to read).
I hope i'm not misreading your code but that's what I see on first scan.

Your Buffer class it flipping between read and write mode. Each read must be followed by a write, that by a read and so on.
You write the buffer initially in your main method.
Now one of your threads reaches if(b.read() > pipe.get(lb+1)) { in Pipeline#run. If that condition evaluates to false, then nothing gets written. And since every other thread must still be the very same if(b.read(), you end up with all reading threads that can't progress. You will either have to write in the else branch or allow multiple reads.

Related

Write out a letter every interval every ms multithreading java

I'm currently working on a problem where I have to:
Write out a letter, x amount of times, after x amount of ms. Use 4 multithreads, 3 of them start right away 1 of them starts when one of the 3 is finished.
For example: A, 10, 100, has to write out A ever 10 times every 100 miliseconds.
Im currently stuck on syncing the multithreads for them to work together at adding one sum rather than them working seporatley. Could you advise how to sync it together for it to write out the above?
Here is my code:
public class PrinterThread extends Thread {
private String letter;
private int internal;
private int amount;
public PrinterThread() {
for (int i = 1; i <= internal; i++) {
System.out.println(letter);
}
synchronized (this){
internal++;
}
try {
Thread.sleep(amount);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
PrinterThread printerThread = new PrinterThread();
PrinterThread printerThread1 = new PrinterThread();
PrinterThread printerThread2 = new PrinterThread();
PrinterThread printerThread3 = new PrinterThread();
printerThread.run();
printerThread1.run();
printerThread2.run();
printerThread3.run();
}
}
Use a BlockingQueue for synchronisation, but you do need to join with the threads from your main method otherwise your main will exit the JVM before the threads finish (or possibly even before they start).
public class PrinterThread implements Runnable {
private String letter;
private int copies;
private int amount;
public PrinterThread(String letter, int copies, int amount) {
this.letter = letter;
this.copies = copies;
this.amount = amount;
}
public void run() {
for (int i = 0; i < copies; i++) {
System.out.println(letter.repeat(copies));
try {
Thread.sleep(amount);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
QUEUE.offer(0);
}
}
public class Main {
private static BlockingQueue<Integer> QUEUE = new ArrayBlockingQueue<>(4); // at least as large as the number of threads
public static void main(String[] args) {
Thread printerThread1 = new Thread(new PrinterThread("A", 10, 100));
Thread printerThread2 = new Thread(new PrinterThread("B", 20, 50));
// etc
printerThread1.start();
printerThread2.start();
// etc
QUEUE.take(); // blocking call
new Thread(new PrinterThread("D", 30, 80)).start();
// wait for threads to finish
printerThread1.join();
printerThread2.join();
// etc
}
}
Disclaimer: This answer was thumbed in via my phone, so it may not work correctly or even compile, but there’s a good chance it will work.
Write out a letter, x amount of times, after x amount of ms. Use 4 multithreads, 3 of them start right away 1 of them starts when one of the 3 is finished.
You obviously need to create a PrinterThread constructor which takes the letter, the amount of times, and amount of millis.
I'm currently stuck on syncing the multithreads for them to work together at adding one sum rather than them working separately.
I'm not sure about the sum. If you are asking how you can start the 3rd thread then there are a number of different ways to do this. I would lock on a lock object and pass in a boolean in the constructor about whether or not the thread should wait() on the lock. As each of the other threads finish they would call notify() on the lock.
private static final Object lock = new Object();
...
public class PrinterThread {
public PrinterThread(char letter, int times, int millis, boolean waitForOthers) {
this.letter = letter;
this.times = times;
this.millis = millis;
if (waitForOthers) {
synchronized (lock) {
// wait for one of the others to notify us
lock.wait();
}
}
}
public void run() {
...
synchronized (lock) {
// notify the lock in case another thread is waiting
lock.notify();
}
}
Then start 3 PrinterThreads with a value of false and 1 of them with a value of true so that it waits.

Preventing deadlock in two thread program

Suppose I have the following code, where one thread generates squares and writes them to a buffer while another thread prints them:
import java.util.*;
public class Something {
public static Buffer buffer = new Buffer();
public static class Buffer {
private int[] buffer;
private static final int size = 10;
//Indexes for putting and taking element form buffer
private int in, out;
//Number of elements in buffer
private int k;
public Buffer() {
buffer = new int[size];
in = 0;
out = 0;
k = 0;
}
public synchronized void put(int e) {
try {
while (k == buffer.length) {
wait();
}
} catch (InterruptedException ex) {
}
buffer[in] = e;
k++;
in = ++in % size;
notifyAll();
}
public synchronized int take() {
try {
while (k == 0) {
wait();
}
} catch (InterruptedException ex) {
}
int e = buffer[out];
buffer[out] = 0;
out = ++out % size;
k--;
notifyAll();
return e;
}
public synchronized boolean notEmpty() {
return k != 0;
}
}
public static class Generator implements Runnable {
int limit;
public Generator(int lim) {
limit= lim;
}
#Override
public void run() {
for (int i = 1; i < limit; i++) {
buffer.put(i * i);
}
}
}
public static class Printer implements Runnable {
private Thread[] generators;
public Printer(Thread[] gen) {
generators = gen;
}
public synchronized boolean nobody() {
for (Thread th : generators) {
if (th.isAlive()) {
return false;
}
}
return true;
}
#Override
public void run() {
int x = 0;
while (!nobody() || buffer.notEmpty()) {
x = buffer.take();
System.out.println(x);
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread generator = new Thread(new Generator(69));
Thread printer = new Thread(new Printer(new Thread[]{generator}));
generator.start();
printer.start();
generator.join();
printer.join();
}
}
Generator should generate squares of numbers until it reaches some limit (limit = 69, in this case). Printer should print all values generated by Generator. Buffer works somewhat like ring buffer. Indexes for putting (in) and taking (out) element are cycling in bounds of buffer size. Buffer has methods for putting and taking elements from buffer. Generator thread cannot put elements in buffer if it is full (that is, there are no zero elements; zero element is 0, for precision sake...). Printer works this way: first it checks if there are any alive generator threads and then checks if buffer contains only zero elements. If neither of these conditions is true, printer thread terminates.
Now, to the problem. I always get printed all squares from 1 to 68, which is expected output of this program. However, on very rare occasion after all numbers had been output I get a deadlock. How rarely? Well, maybe in 1 out of 100 executions of program. I had to keep hitting "F6" on NetBeans like crazy to get a deadlock. And yes, I know that I can test this simply putting all main code in for loop.
Conversely, if I comment out print line in Printers' run method, deadlock happens almost all the time. Here:
#Override
public void run() {
int x = 0;
while (!nobody() || buffer.notEmpty()) {
x = buffer.take();
//System.out.println(x);
}
}
I do not expect this behavior, because element still gets taken from buffer and generator should be awoken.
Why does this happen? And how do I fix it?
Sorry if question isn't clear enough, I'll try to clarify it as best I can if needed.
I think I fount the problem. Here is what I got: There is a very short moment in time, where the Generator thread is still alive (i.e. Thread.isAlive() will return true), but the Generator has left the for-loop within run(). If the Printer queries its while-condition within its run() at this point in time, it will try to take() something, that is not there (and never will be). Indeed, you can verify, that the Generator always finishes, meaning termination detection on the side of the Printer is faulty. For a hot fix, you can simply add a magic constant is Printers while condition:
#Override
public void run() {
int x = 0;
int count = 0;
while (++count < 69) {
x = buffer.take();
System.out.println(x);
}
}
For a clean termination detection, you could set some common flag-variable to false, signaling that the Generator has finished work and the Printer can stop working. But this has to be done in a synchronized manner, meaning the Printer is not allowed to query this condition, while the Generator is after its last push, but before it sets this common flag.

JVM seems to stop context switching very quickly

I'm implementing the naive version of the Producer-Consumer concurrency problem. And it the threads are switched between at first very quickly but then stop around i = 50. Adding additional print statements for some reason allows the JVM to context switch the threads and complete the program.
Why doesn't the JVM context switch the threads so that the program will complete?
// Producer - Consumer problem
// Producer constantly puts items into array, while consumer takes them out
class IntBuffer {
private int[] buffer;
private int index;
public IntBuffer(int size) {
buffer = new int[size];
index = 0;
}
public void add(int item) {
while (true) {
if (index < buffer.length) {
buffer[index] = item;
index++;
return;
}
}
}
public int remove() {
while (true) {
if (index > 0) {
index--;
int tmp = buffer[index];
buffer[index] = 0;
return tmp;
}
}
}
public void printState() {
System.out.println("Index " + index);
System.out.println("State " + this);
}
public String toString() {
String res = "";
for (int i = 0; i < buffer.length; i++) {
res += buffer[i] + " ";
}
return res;
}
}
class Producer extends Thread {
private IntBuffer buffer;
public Producer(IntBuffer buffer) {
this.buffer = buffer;
}
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("added " + i);
buffer.add(i);
}
}
}
class Consumer extends Thread {
private IntBuffer buffer;
public Consumer(IntBuffer buffer) {
this.buffer = buffer;
}
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("removed " + i);
buffer.remove();
}
}
}
public class Main {
public static void main(String[] args) {
IntBuffer buf = new IntBuffer(10);
Thread t1 = new Thread(new Producer(buf));
Thread t2 = new Thread(new Consumer(buf));
t1.start();
t2.start();
System.out.println(buf);
}
}
Your question does not provide enough details to give an answer with a confidence(at least, it is not clear where those additional print statements go), so I'll make some(reasonable) guesses here.
Your code is not correct. IntBuffer is not thread-safe, but it is accessed from multiple threads.
Any operations on the IntBuffer do not establish a happens-before relationship, so the changes made by one thread may be not visible for another thread. That's why the Producer thread can "believe" that the buffer is full while the Consumer thread "believes" that it is empty. In this case the program never terminates.
This two statements are not guesses, they are facts based on the Java memory model. And here goes my guess why the additional print statements sorta fix it:
In many JVM implementations, the println methods uses syncronization internally. That's why a call to it creates a memory fence and makes changes made in one thread visible to the other one, eliminating the issue described in 2).
However, if you really want to solve this problem, you should make the IntBuffer thread-safe.
At the minimum you need the volatile keyword on both the buffer and index. Second, you need to access index only once under the true arm of the ifs you have there. Even after that, you will face out of bounds access at 10, you will need more fixing to work around that. Your buffer is de facto stack. So, even after all of this, your remove() can be working with stale index, thus you will be removing in the middle of the stack. You could use 0 as special value marking the slot already handled end empty.
With all of this, I do not think your code is easily salvageable. It pretty much needs complete rewrite using proper facilities. I agree with #kraskevich:
#StuartHa Naive usually means simple(and most likely inefficent) solution, not an incorrect one.

Parallel Implementation of DFS for undirected graph

I have been trying to implement a parallel Depth First Search in Java for undirected graph. I wrote this code but it doesn't work properly. It doesn't speed-up.
Main method:
package dfsearch_v2;
import java.util.Calendar;
import java.util.Stack;
import java.util.Random;
public class DFSearch_v2 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
long ts_b, ts_e;
int el_count=100;
int thread_count = 4;
int vertices[][]; // graph matrix
boolean isVisited[] = new boolean[el_count];
for(int i=0;i<el_count;i++){
for(int j=0;j<el_count;j++){
Random boolNumber = new Random();
boolean edge = boolNumber.nextBoolean();
vertices[i][j]=edge ? 1 :
}
}
DFSTest r[] = new DFSTest[thread_count];
ts_b = Calendar.getInstance().getTimeInMillis();
for(int i = 0; i < thread_count; i++) {
r[i] = new DFSTest(el_count,vertices,isVisited);
r[i].start();
}
for(int i = 0; i < thread_count;
try {
r[i].join();
} catch (InterruptedException e) {
}
}
ts_e = Calendar.getInstance().getTimeInMillis();
System.out.println("Time "+(ts_e-ts_b));
}
Thread implementation:
package dfsearch_v2;
import java.util.Stack;
public class DFSTest extends Thread {
int numberOfNodes;
int adj[][];
boolean isVisit[];
public DFSTest(int numberOfNodes, int adj[][],boolean isVisit[]){
this.numberOfNodes = numberOfNodes;
this.adj=adj;
this.isVisit=isVisit;
}
public void run()
{
int k,i,s=0;
Stack<Integer> st = new Stack<>();
for(k=0; k < numberOfNodes; k++) isVisit[k]=false;
for (k = numberOfNodes - 1; k >= 0; k--) {
st.push(k);
}
DFSearch(st, isVisit);
}
private void DFSearch(Stack<Integer> st,boolean isVisit[]){
synchronized(isVisit){
int i,k;
while (!st.empty()) {
k=st.pop();
if (!isVisit[k]) {
isVisit[k] = true;
System.out.println("Node "+k+" is visit");
for(i=numberOfNodes-1; i>=0; i--)
if(adj[k][i]==1) st.push(i);
}
}
}
}
}
Could anybody, please, help me? I am really new to parallel programming.
Thanks
If I understand your program correctly, you are locking on the isVisit array which is shared between all threads - this means that you're not going to get any speedup because only one thread is able to make progress. Try using a ConcurrentHashMap or ConcurrentSkipListMap instead.
// shared between all threads
ConcurrentMap<Integer, Boolean> map = new ConcurrentHashMap<>();
public boolean isVisit(Integer integer) {
return map.putIfAbsent(integer, Boolean.TRUE) != null;
}
private void DFSearch(Stack<Integer> st) {
if(!isVisit(st.pop())) {
...
}
}
The concurrent maps use sharding to increase parallelism. Use the putIfAbsent method in isVisit to avoid a data race (you only want the method to return false for one thread).
As for how to divide the work up among multiple threads, use a ConcurrentLinkedQueue of worker threads. When a thread has no more work to perform, it adds itself to the worker thread queue. When a thread has two edges to traverse, it polls the worker thread queue for an available worker thread, and if one is available it assigns one of the edges to the worker thread. When all threads are on the available thread queue then you've traversed the entire list.
You shouldn't need to synchronize on isVisit, which is what is destroying your parallelism. Multiple readers/multiple writers for a Boolean array should be quite safe.
If at all possible, you should avoid dependencies between threads. To this end, don't use a shared stack (if this is what your code is doing -- it's unclear).
In your case, the amount of work done per vertex is tiny, so it makes sense to batch up work in each thread and only consider handing work on to other threads once some backlog threshold is reached.
I changed the approach a little. Now it uses one global stack which is shared by all the threads and n local stacks where n is the number of threads. Each thread stores the nodes of its sub-tree in its local stack. Initially the global stack contains the root of the tree and only one thread gets access to it while the other threads are waiting to be woken up by the working thread. The working thread retrieves and processes the root from the global stack, adds one successor to its local stack then pushes the rest of the successors, if they exist, to the global stack to be processed by other threads and wakes up all the waiting threads. All the other threads follow the same approach (i.e. when threads get a node from the global stack they push one successor to their local stack and the rest to the global stack then start accessing their local stack until it becomes empty).
Yet, it doesn't speed up. I'll be thankful to all of your further ideas.
Main method:
package dfsearch_v2;
import java.util.Calendar;
import java.util.Random;
public class DFSearch_v2 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
long ts_b, ts_e;
//number of nodes
int el_count=400;
int thread_count = 8;
int gCounter=0;
int vertices[][] = new int[el_count][el_count]; // graph matrix
boolean isVisited[] = new boolean[el_count];
for(int i=0;i<el_count;i++){
for(int j=0;j<el_count;j++){
Random boolNumber = new Random();
boolean edge = boolNumber.nextBoolean();
vertices[i][j]=edge ? 1 : 0;
}
}
DFSearch2 r[] = new DFSearch2[thread_count];
ts_b = Calendar.getInstance().getTimeInMillis();
for(int i = 0; i < thread_count; i++) {
r[i] = new DFSearch2(el_count,vertices,isVisited,gCounter);
r[i].start();
}
for(int i = 0; i < thread_count; i++) {
try {
r[i].join();
} catch (InterruptedException e) {
}
}
ts_e = Calendar.getInstance().getTimeInMillis();
System.out.println("Time "+(ts_e-ts_b));
}
}
Thread implementation:
package dfsearch_v2;
import java.util.Stack;
public class DFSearch2 extends Thread{
private boolean isVisit[];
private final Stack<Integer> globalStack;
int numberOfNodes;
//traversal is done ?
boolean isDone;
int adj[][];
// count visited nodes
int gCounter;
public DFSearch2(int number_Nodes,int adj[][],boolean isVisit[],int gCounter){
this.numberOfNodes=number_Nodes;
this.isVisit = isVisit;
this.globalStack = new Stack<>();
this.isDone=false;
this.adj=adj;
this.gCounter=gCounter;
this.globalStack.push(number_Nodes-1);
}
public void run(){
// local stack
Stack<Integer> localStack = new Stack<>();
while (!isDone) {
int k;
synchronized(globalStack){
k = globalStack.pop();
//pop until k is not visited
while (isVisit[k]) {
if(globalStack.empty()) {
isDone=true;
return;
}else{
k=globalStack.pop();
}
}
}
// traverse sub-graph with start node k
DFSearchNode(localStack,k);
yield();
if(globalStack.empty()) {
isDone = true;
}
// if gCounter is not null unvisited node are pushed in globalStack
if(isDone&&gCounter<numberOfNodes){
isDone=false;
//unvisited nodes are pushed in globalStack
for (int i = 0; i < isVisit.length; i++) {
if (!isVisit[i]) {
globalStack.push(i);
}
}
}
}
}
synchronized private void DFSearchNode(Stack<Integer> localStack, int k){
localStack.push(k);
while (!localStack.empty()) {
int s=localStack.pop();
if (!isVisit[s]) {
isVisit[s] = true;
gCounter++;
//System.out.println("Node "+s+" is visit");
//first element is pushed into localStack and anothers in globalStack
boolean flag = true; // local or global stack (true -> local; false ->global )
for(int i=numberOfNodes-1; i>=0; i--)
{
//
if(i==s) continue;
//push another successors in global stack
if(adj[s][i]==1&&!flag&&!isVisit[s]){//visited nodes are not pushed in globalStack
globalStack.push(i);
}
//push first successor in global stack
if(adj[s][i]==1&&flag&&!isVisit[s]) //visited nodes are not pushed in localStack
{
localStack.push(i);
flag=false; //only first element is pushed into localStack
}
}
}
}
}
}

Semaphores: Critical Section with priorities

I'm writing a program in Java that deals with Semaphores for an assignment. I'm still new to the idea of Semaphores and concurrency.
The description of the problem is as follows:
A vector V[] of booleans. V[i] is "True"if Pi needs to use the critical section.
A vector of binary semaphores B[] to block processes from entering their critical section: B[i] will be the semaphore blocking process Pi.
A special scheduler process SCHED is used whenever a blocked process needs to be awakened to use the critical section.
SCHED is blocked by waiting on a special semaphore S
When a process Pi needs to enter the critical section, it sets V[i] to "True", signals the semaphore S and then waits on the semaphore B[i].
Whenever SCHED is unblocked, it selects the process Pi with the smallest index i for which V[i] is "True". Process Pi is then awakened by signaling B[i] and SCHED goes back to sleep by blocking on semaphore S.
When a process Pi leaves the critical section, it signals S.
This is my code:
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();
}
}
}
I believe my logic here is correct but I'm getting a lot of errors (such as Exception in thread "Thread-1" java.lang.NullPointerException). Can any shed some light on what I'm doing wrong & provide me with some help. It's greatly appreciated!
Your NPE is probably due to the fact that you never initialize your Semaphore array - but its hard to say without a proper stack trace.
Two pieces of advice:
1) You might want to give your class variables more meaningful names than :
B
N
S
V.
Imagine walking away from this project and revisiting it in 4 months and had to read through that.
2) Figure out your class model on on a white board before writing any code. You have methods that take semaphores with the same name as some of your static fields. What are the relationships of the objects in your program? If you don't know, odds are your program doesn't know either.

Categories

Resources