This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Hello I have a Java application that takes an input number of operations to perform and it run different threads for each operation:
//create operations to execute
Thread t[] = new Thread [n_operations];
//we create a Bank with N accounts
Bank mybank = new Bank(N);
//execute a separate thread per operation
for (int i = 0; i < n_operations; i++) {
int id = i;
Operation o = new Operation(mybank, id);
t[i]= new Thread (o);
t[i].start();
}
for (int i=0;i<N;i++){
try{
t[i].join();
}catch(Exception e){;}
}
Now I need to perform concurrent transfer on the accounts, where the Bank class is defined like this:
public class Bank {
private static Account[] accounts;
final int MAX_balance = 100000;
int MAX_accounts = 0;
/* Create accounts of a bank */
public Bank (int N) {
accounts = new Account[N];
MAX_accounts = N;
for (int i = 0; i < N; i++)
accounts[i] = new Account (i, 1000);
}
public int getN(){
return MAX_accounts;
}
public synchronized int transfer(int from, int to, int amount) {
synchronized (accounts[from]){
synchronized (accounts[to]){
if (accounts[from].balance () < amount) {
try{
System.out.println("Error during transfer: Not enough Money");
}
catch(Exception err){
return 1;
}
}
accounts[from].sub(amount);
accounts[to].add(amount);
}
}
return 0;
}
}
When the program performs the operations:
public class Operation implements Runnable {
private Bank b;
int id;
Random r;
private final int MAX_TRANSFERENCIAS = 1000;
public Operation (Bank b, int id) {
this.b = b;
this.id = id;
}
public int syncronize(){
return 1;
}
public void run () {
r = new Random();
if(b == null)
throw new RuntimeException("b is null!");
if(r == null)
throw new RuntimeException("r is null!");
int max = b.getN();
//depend if there is a conflict or not
b.transfer (id,r.nextInt(max),r.nextInt(100));
}
}
I get a series of errors like this message:
at Bank.transfer(Bank.java:28) /* which is "synchronized (accounts[from]){" */
at Operation.run(Operation.java:33) /* which is "b.transfer
(id,r.nextInt(max),r.nextInt(100));" */
at java.lang.Thread.run(Unknown Source)
java.lang.ArrayIndexOutOfBoundsException: 4714
Do you think the Synchronization is ok?
Any suggestions? Many thanks
UPDATE (I can't answer myself)
There is a concept error in the main loop (for i..to n_operations),
the function is passing "int id = i;" as parameter for the source_account, while the n_operation number is bigger than the max value of the array, so the compiler reasonably says: ArrayIndexOutOfBoundsException.
As final contribution I would ask you to kindly check if the Synchronization is done correctly, as I am not an expert in multithreading. Many thanks again, and sorry for badly formulate the question this morning....
Edit:
Now that we know that the following line is the source of the NPE:
b.transfer (id,r.nextInt(max),r.nextInt(100));
So most likely b or r is null. You should put a break point there and debug into it to see if they are. You could also use assert or logging to display the values. Remember also that id or max could also cause a NPE if either is an Integer that is null and gets auto-boxed.
This wouldn't cause your NPE but be careful that n_operations may not be == 100? You are starting n_operations threads but joining with 100 of them:
for (int i=0;i<100;i++){
try {
t[i].join();
} catch(Exception e){;}
}
I always use the length of the array in these cases so you don't have a mismatch between what was allocated:
for (int i = 0; i < t.length; i++) {
Also, at the very least you should always log or print your exceptions. Catching and dropping exceptions often means you are hiding important debugging information.
} catch(Exception e){ e.printStackTrace(); }
One of the variables you are using in run() is null, but which one? Try adding the following to the beginning of Operation.run():
if(b == null)
throw new RuntimeException("b is null!");
if(r == null)
throw new RuntimeException("r is null!");
I presume that the lines you showed from run() include line 27. If not, please post the full source code for run().
Related
I'm given code of a Banking example and I'm trying to figure out if this does produce a deadlock or not. If so, what part of the code achieves it? I would also like to know how I would alter the code to prevent deadlocks. I know it has something to do with the ordering of the methods but this code specifically confuses me. I'm new to networked programming so I'm still a little confused on this topic.
I have written this in Java.
public class Bank
{
public Bank(int n, double initialBalance)
{
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
bankLock = new ReentrantLock();
sufficientFunds = bankLock.newCondition();
}
public synchronized void transfer(int from, int to, double amount) throws InterruptedException
{
bankLock.lock();
try
{
while (accounts[from] < amount)
sufficientFunds.await();
System.out.print(Thread.currentThread());
accounts[from] -= amount;
System.out.printf(" %10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
sufficientFunds.signalAll();
}
finally
{
bankLock.unlock();
}
}
public synchronized double getTotalBalance()
{
bankLock.lock();
try
{
double sum = 0;
for (double a : accounts)
sum += a;
return sum;
}
finally
{
bankLock.unlock();
}
}
public int size()
{
return accounts.length;
}
public class DeadlockApp
{
public static void main(String[] args)
{
Bank bank = new Bank(NACCOUNTS,INITIAL_BALANCE);
for (int i = 0; i< NACCOUNTS; i++)
{
int fromAccount = i;
Runnable r = () ->
{
try
{
while (true)
{
int toAccount = (int) (bank.size() * Math.random());
double amount = MAX_AMOUNT * Math.random();
bank.transfer(fromAccount, toAccount, amount);
Thread.sleep((int)(DELAY * Math.random()));
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r);
t.start();
}
}
When I ran the code it was very slow and only produced two results so I couldn't tell if it was the deadlock that was going continuously or my IDE was just lagging.
The basic requirement for deadlocking is that two or more threads attempt to acquire a series of locks, but acquire them in varying order.
You have two locks in play, but your threads are all executing the same code, which has a fixed order of lock acquisition, and both locks can be recursively acquired, so there's no deadlock.
More specifically, only one thread at a time is executing in transfer by virtue of it being synchronized.
The locks are acquired in this order:
The Bank monitor (by 'synchronized' on transfer)
banklock (in transfer)
The Bank monitor again ('synchronized' on getTotalBalance) - but we hold it already so it will not block
banklock (in getTotalBalance) but we hold it already so it won't block
No deadlock, so there's some other cause for 'slowness'. My guess would be on how long the random actions take to build up sufficient funds.
I am new to multi threading. Literally. And I am pretty new to Java overall. HOwever, I am making a simulation and the thread seem to be working well except I occasionally have the program become unresponsive and once it said out of memory error. I assume this is because I am creating too many threads? At the point it normally does this I have over 2000 threads running at the same time. I can adjust the code (i.e reduce the number of customers or increase time between ticks) to release the pressure on the system but I am wondering if there is something I could be doing to help ease the burden within each thread itself. I'm pretty sure it isn't a deadlock since the code runs fine if I do the above but run it for longer so the same amount of customers come through. I will show the relevant parts of the code and if more is required I am happy to put this up. Please I don't understand this very well, so some very simple and helpful explanations would be greatly appreciated, since if the comment is too complex I probably wont' know how to implement it.
This is the main class that creates the thread.
CheckoutFloor checkoutFloor = new CheckoutFloor();
checkoutFloor.addCheckoutOperators(checkoutOperators);
int tick = 0;
int customers = 0;
while (tick < simulationTime) {
for (int i = 0; i < 2; i++) {
Random rand = new Random();
int random = rand.nextInt(100) + 1;
if (random <= 50) {
customerRunnable customer = new customerRunnable(checkoutFloor);
Thread t = new Thread(customer);
t.start();
tick++;
}
else {
tick++;
}
Here is the runnable code:
public void run() {
try {
customer.addRandomShopTime();
while (customer.shopTime > 0) {
Thread.sleep(1);
customer.setShopTime();
}
CheckoutOperator checkoutOperator = checkoutFloor.weightedCheckoutDeterminator();
checkoutOperator.addCustomer(customer);
while (customer.checkoutTime > 0) {
Thread.sleep(1);
if (checkoutOperator.customerList.get(0) == customer) {
customer.setCheckoutTime();
}
}
checkoutOperator.removeCurrentCustomer();
} catch (InterruptedException e) {
}
And here are the relevant methods.
public synchronized void addCustomer(Customer newCustomer) {
customerList.add(newCustomer);
System.out.println("no. of customers" + counter);
counter++;
}
public synchronized CheckoutOperator weightedCheckoutDeterminator() {
int totalCustomers = 0;
int totalCustomersAdj = 0;
for (int i = 0; i < checkoutOpList.size(); i++) {
totalCustomers += getCheckoutOperator(i).getCustomerListLength();
}
if (totalCustomers == 0) {
return getCheckoutOperator(0);
} else {
totalCustomersAdj = (checkoutOpList.size() * totalCustomers) - totalCustomers;
int randomNumber = 0;
try {
randomNumber = new Random().nextInt(totalCustomersAdj) + 1;
} catch (IllegalArgumentException ex) {
return checkoutOpList.get(0);
}
for (int i = 0; i < checkoutOpList.size(); i++) {
int operatorCustLength = (getCheckoutOperator(i).getCustomerListLength());
if (randomNumber <= (totalCustomers - operatorCustLength)) {
return getCheckoutOperator(i);
} else {
randomNumber = randomNumber - (totalCustomers - operatorCustLength);
}
}
return checkoutOpList.get(0); //HOPEFULLY UNREACHABLE!!!
}
I'm just wondering if, due to my lack of knowledge, there is anything I am missing that woudl help the flow a bit more and help it run faster?
[edit: I should add that under normal conditions I would never have 2000 threads running and this is me pushing the system to the max. I suspect that this IS the problem and I guess I am asking if there is something else I am missing due to my lack of knowledge. I just don't like the idea that if someone changes the code to make it more intensive that it might crash.].
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Can't figure this out, I've created a simple class of coordinates to hold x and y ints. In another class I have a global array of Coordinates declared called "ords". In my loop I'm adding Coordinates. When trying to use method getX() and getY() from the Coordinates class in my getaction method, I get a null pointer exception. I'm sure the objects are not null, but I still can't figure out whats going wrong. Any help appreciated.
import java.util.*;
import org.w2mind.net.*;
import java.io.Serializable;
public class ConorsMind implements Mind
{
int [][] surroundings = new int [12][16];
Coordinates [] ords = new Coordinates [192];
int currentX;
int currentY;
//====== Mind must respond to these methods: ==========================================================
// newrun(), endrun()
// getaction()
//======================================================================================================
public void newrun() throws RunError
{
}
public void endrun() throws RunError
{
}
private void formTwoDimmensional(int [] someArray)
{
int counter = 0;
int n=0;
for(int i = 0; i < 15; i++)
{
for(int z = 0; z < 12; z++)
{
surroundings[z][i] = someArray[counter];
if(surroundings[z][i] ==0) {
currentX=z;
currentY=i;
}
else if(surroundings[z][i]==4){
ords[n]= new Coordinates(z,i);
n++;
}
System.out.print(z+" , "+i+": "+surroundings[z][i]);
System.out.println();
counter++;
}
}
}
public Action getaction ( State state )
{
String s = state.toString();
String[] x = s.split(",");
int act =MinerWorldUpdated.NO_ACTIONS;
int counter = 0;
int [] surround = new int [192];
//in this way user will have ability to see what surrounds him
for(int i = 11; i < 203; i++)
{
surround[counter] = Integer.parseInt(x[i]);
counter++;
}
formTwoDimmensional(surround);
int [] response = new int [x.length];
for(int i = 0; i < x.length; i++)
{
response[i] = Integer.parseInt ( x[i] );
}
System.out.println("Current position: "+currentX+" ,"+currentY);
int coalX=ords[0].getX();
int coalY=ords[0].getY();
System.out.println("Coal position: "+coalX+" ,"+coalY);
if(coalX != 0 && coalY !=0)
{
if(coalX>currentX)
{
act=MinerWorldUpdated.ACTION_DOWN;
}
else if(coalY<currentY)
{
act=MinerWorldUpdated.ACTION_LEFT;
}
else if(coalX<currentX)
{
act=MinerWorldUpdated.ACTION_DOWN;
}
else if(coalY<currentY)
{
act=MinerWorldUpdated.ACTION_LEFT;
}
}
String a = String.format ( "%d", act );
return new Action ( a );
}
}
class Coordinates implements Serializable
{
private int x;
private int y;
public Coordinates(int x1, int y1)
{
x=x1;
y=y1;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
Error is as follows:
java.lang.NullPointerException
at ConorsMind.getaction(ConorsMind.java:146)
The error is stemming from the following two lines:
int coalX=ords[0].getX();
int coalY=ords[0].getY();
I am calling formTwoDimensional() and its working perfectly, the ords objects are being created successfully and are not null as testing with System.out.println(ords[n].getX()) is printing the expected result when placed in my else if(surroundings[z][i]==4) block.
You need to make sure that you're calling formTwoDimensional(). If you are indeed, then it's likely that you're not ever getting into your else if block in the nested for loop, and hence ords[0] is never actually being set, so when you try to access it, it's null.
The other thing to do, if you don't want to post the rest of your code, is to add some more debugging code. See below the boolean zero_pos_set. But make sure that you see the print "Zero pos set" before your program crashes. My bet is that you don't.
public class ConorsMind implements Mind
{
int [][] surroundings = new int [12][16];
Coordinates [] ords = new Coordinates [192];
boolean zero_pos_set = false;
private void formTwoDimmensional(int [] someArray)
{
int counter = 0;
int n=0;
for(int i = 0; i < 15; i++) {
for(int z = 0; z < 12; z++) {
surroundings[z][i] = someArray[counter];
if(surroundings[z][i] ==0) {
currentX=z;
currentY=i;
} else if(surroundings[z][i]==4) {
zero_pos_set = true;
ords[n]= new Coordinates(z,i);
n++;
}
counter++;
}
}
}
public Action getaction ( State state ) {
if(zero_pos_set) {
System.out.println("Zero pos set!");
}
int coalX=ords[0].getX();
int coalY=ords[0].getY();
System.out.println("Coal position: "+coalX+" ,"+coalY);
return new Action ( a );
}
}
Based on all of the debugging information posted within this thread, it seems that in your getaction() function, you're being passed some state, that doesn't contain 4.
When you parse this information and pass it to formTwoDimensional(), you will never reach the else if block, and so ords[0], or any other ords[n], will never be set.
As a result, when you try to access ords[0] back in your getaction() function, you actually get null, and hence your NullReferenceException.
It's an order of operations issue.
If you never make a call to formTwoDimmensional(), you'll never initialize anything inside of your array. Be sure you're calling that first.
The actual NPE happens when you attempt to call coalX=ords[0].getX();, which won't work if ords[0] is null.
I am new to Java and trying to write a method that finds the maximum value in a 2D array of longs.
The method searches through each row in a separate thread, and the threads maintain a shared current maximal value. Whenever a thread finds a value larger than its own local maximum, it compares this value with the shared local maximum and updates its current local maximum and possibly the shared maximum as appropriate. I need to make sure that appropriate synchronization is implemented so that the result is correct regardless of how to computations interleave.
My code is verbose and messy, but for starters, I have this function:
static long sharedMaxOf2DArray(long[][] arr, int r){
MyRunnableShared[] myRunnables = new MyRunnableShared[r];
for(int row = 0; row < r; row++){
MyRunnableShared rr = new MyRunnableShared(arr, row, r);
Thread t = new Thread(rr);
t.start();
myRunnables[row] = rr;
}
return myRunnables[0].sharedMax; //should be the same as any other one (?)
}
For the adapted runnable, I have this:
public static class MyRunnableShared implements Runnable{
long[][] theArray;
private int row;
private long rowMax;
public long localMax;
public long sharedMax;
private static Lock sharedMaxLock = new ReentrantLock();
MyRunnableShared(long[][] a, int r, int rm){
theArray = a;
row = r;
rowMax = rm;
}
public void run(){
localMax = 0;
for(int i = 0; i < rowMax; i++){
if(theArray[row][i] > localMax){
localMax = theArray[row][i];
sharedMaxLock.lock();
try{
if(localMax > sharedMax)
sharedMax = localMax;
}
finally{
sharedMaxLock.unlock();
}
}
}
}
}
I thought this use of a lock would be a safe way to prevent multiple threads from messing with the sharedMax at a time, but upon testing/comparing with a non-concurrent maximum-finding function on the same input, I found the results to be incorrect. I'm thinking the problem might come from the fact that I just say
...
t.start();
myRunnables[row] = rr;
...
in the sharedMaxOf2DArray function. Perhaps a given thread needs to finish before I put it in the array of myRunnables; otherwise, I will have "captured" the wrong sharedMax? Or is it something else? I'm not sure on the timing of things..
I'm not sure if this is a typo or not, but your Runnable implementation declares sharedMax as an instance variable:
public long sharedMax;
rather than a shared one:
public static long sharedMax;
In the former case, each Runnable gets its own copy and will not "see" the values of others. Changing it to the latter should help. Or, change it to:
public long[] sharedMax; // array of size 1 shared across all threads
and you can now create an array of size one outside the loop and pass it in to each Runnable to use as shared storage.
As an aside: please note that there will be tremendous lock contention since every thread checks the common sharedMax value by holding a lock for every iteration of its loop. This will likely lead to poor performance. You'd have to measure, but I'd surmise that letting each thread find the row maximum and then running a final pass to find the "max of maxes" might actually be comparable or quicker.
From JavaDocs:
public interface Callable
A task that returns a result and may
throw an exception. Implementors define a single method with no
arguments called call.
The Callable interface is similar to Runnable, in that both are
designed for classes whose instances are potentially executed by
another thread. A Runnable, however, does not return a result and
cannot throw a checked exception.
Well, you can use Callable to calculate your result from one 1darray and wait with an ExecutorService for the end. You can now compare each result of the Callable to fetch the maximum. The code may look like this:
Random random = new Random(System.nanoTime());
long[][] myArray = new long[5][5];
for (int i = 0; i < 5; i++) {
myArray[i] = new long[5];
for (int j = 0; j < 5; j++) {
myArray[i][j] = random.nextLong();
}
}
ExecutorService executor = Executors.newFixedThreadPool(myArray.length);
List<Future<Long>> myResults = new ArrayList<>();
// create a callable for each 1d array in the 2d array
for (int i = 0; i < myArray.length; i++) {
Callable<Long> callable = new SearchCallable(myArray[i]);
Future<Long> callResult = executor.submit(callable);
myResults.add(callResult);
}
// This will make the executor accept no new threads
// and finish all existing threads in the queue
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
// now compare the results and fetch the biggest one
long max = 0;
for (Future<Long> future : myResults) {
try {
max = Math.max(max, future.get());
} catch (InterruptedException | ExecutionException e) {
// something bad happend...!
e.printStackTrace();
}
}
System.out.println("The result is " + max);
And your Callable:
public class SearchCallable implements Callable<Long> {
private final long[] mArray;
public SearchCallable(final long[] pArray) {
mArray = pArray;
}
#Override
public Long call() throws Exception {
long max = 0;
for (int i = 0; i < mArray.length; i++) {
max = Math.max(max, mArray[i]);
}
System.out.println("I've got the maximum " + max + ", and you guys?");
return max;
}
}
Your code has serious lock contention and thread safety issues. Even worse, it doesn't actually wait for any of the threads to finish before the return myRunnables[0].sharedMax which is a really bad race condition. Also, using explicit locking via ReentrantLock or even synchronized blocks is usually the wrong way of doing things unless you're implementing something low level (eg your own/new concurrent data structure)
Here's a version that uses the Future concurrent primitive and an ExecutorService to handle the thread creation. The general idea is:
Submit a number of concurrent jobs to your ExecutorService
Add the Future returned backed from submit(...) to a List
Loop through the list calling get() on each Future and aggregating the result
This version has the added benefit that there is no lock contention (or locking in general) between the worker threads as each just returns back the max for its slice of the array.
import java.util.concurrent.*;
import java.util.*;
public class PMax {
public static long pmax(final long[][] arr, int numThreads) {
ExecutorService pool = Executors.newFixedThreadPool(numThreads);
try {
List<Future<Long>> list = new ArrayList<Future<Long>>();
for(int i=0;i<arr.length;i++) {
// put sub-array in a final so the inner class can see it:
final long[] subArr = arr[i];
list.add(pool.submit(new Callable<Long>() {
public Long call() {
long max = Long.MIN_VALUE;
for(int j=0;j<subArr.length;j++) {
if( subArr[j] > max ) {
max = subArr[j];
}
}
return max;
}
}));
}
// find the max of each slice's max:
long max = Long.MIN_VALUE;
for(Future<Long> future : list) {
long threadMax = future.get();
System.out.println("threadMax: " + threadMax);
if( threadMax > max ) {
max = threadMax;
}
}
return max;
} catch( RuntimeException e ) {
throw e;
} catch( Exception e ) {
throw new RuntimeException(e);
} finally {
pool.shutdown();
}
}
public static void main(String args[]) {
int x = 1000;
int y = 1000;
long max = Long.MIN_VALUE;
long[][] foo = new long[x][y];
for(int i=0;i<x;i++) {
for(int j=0;j<y;j++) {
long r = (long)(Math.random() * 100000000);
if( r > max ) {
// save this to compare against pmax:
max = r;
}
foo[i][j] = r;
}
}
int numThreads = 32;
long pmax = pmax(foo, numThreads);
System.out.println("max: " + max);
System.out.println("pmax: " + pmax);
}
}
Bonus: If you're calling this method repeatedly then it would probably make sense to pull the ExecutorService creation out of the method and have it be reused across calls.
Well, that definetly is an issue - but without more code it is hard to understand if it is the only thing.
There is basically a race condition between the access of thread[0] (and this read of sharedMax) and the modification of the sharedMax in other threads.
Think what happens if the scheduler decides to let no let any thread run for now - so when you are done creating the threads, you will return the answer without modifying it even once! (of course there are other possible scenarios...)
You can overcome it by join()ing all threads before returning an answer.
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.