-1

I got this question asked in an interview. I had to create a utility function which cannot be accessed by more than n number of a thread at any point of time. So,if (n+1)th thread requests then it should wait until any of the previous thread completes.

Here is what i offered as a solution :

class MyMathUtil implements Runnable {
double a;
double b;
String name="demo";
Thread t;
static int currentCount=0;
static int maxCount=2;

MyMathUtil(double v1,double v2) {
        a = v1;
        b = v2;
        t = new Thread(this, name);
        System.out.println("New thread: " + t);
        t.start();
    }
 public void InternalPow(double a,double b){
     System.out.println("Power of "+a+" and "+b+" : "+Math.pow(a, b));
 }

    public void run() {
        try {
            if(currentCount<maxCount){
                currentCount++;
                InternalPow(a,b);
                notify();
            }else{
                synchronized (Thread.currentThread()) {
                    Thread.currentThread().wait();; 
                }
            }


        } catch (InterruptedException e) {
            System.out.println(name + "Interrupted");
        }
        System.out.println(name + " exiting.");
    }
}

class TestMyMathUtil {
public static void main(String args[]) {
     new MyMathUtil(10.2,8);
     new MyMathUtil(11,56);
     new MyMathUtil(10.2,9);
     }
}

But the third request(which is the (n+1)th request) doesn't gets executed ever.Can anyone explain why? An even better solution would also be appreciated.

Update : using the suggestions given i have used a semaphore here but the problem that is here is that the next thread that will be awakened is non-deterministic. What if i want the thread to be awakened next has to be of some priority that i can give ?

Here is the new implementation ;

class MyMathUtil2 implements Runnable {
    double a;
    double b;
    String name = "demo";
    Thread t;
    //static int currentCount = 0;
    static int MAX_COUNT = 2;

    private final Semaphore available = new Semaphore(MAX_COUNT, true);

    MyMathUtil2(double v1, double v2) {
        a = v1;
        b = v2;
        t = new Thread(this, name);
        System.out.println("New thread: " + t);
        t.start();
    }

    public void InternalPow(double a, double b) throws InterruptedException {
        available.acquire();
        try {
            System.out.println("Power of " + a + " and " + b + " : " + Math.pow(a, b));
        } finally {
            available.release();
        }

    }

    public void run() {
        try {
            InternalPow(a, b);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class TestMyMathUtil2 {
    public static void main(String args[]) {
        new MyMathUtil2(10.2, 8);
        new MyMathUtil2(11, 56);
        new MyMathUtil2(10.2, 9);
        new MyMathUtil2(2, 3);
        new MyMathUtil2(4, 5);
    }
}
ritesh
  • 45
  • 7

1 Answers1

3

You can't wait for the current thread, it will never get notified. You need to wait on and notify the same object. Plus you never decrement currentCount!

What you need is a Sempahore (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Semaphore.html). Create it with the max count, for example:

private final Semaphore available = new Semaphore(MAX_COUNT, true);

public void InternalPow(double a, double b) {
    available.aquire();
    try {
        // Code here
    } finally {
        available.release();
    }
}
ewramner
  • 5,810
  • 2
  • 17
  • 33
  • asked here https://stackoverflow.com/questions/50128812/how-to-give-priority-to-the-threads-waiting-in-a-semaphore – ritesh May 02 '18 at 07:01