Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allowing only two thread to operate on a function

I have an unusual problem. I have a function, operation in this function can be done by two threads at a time.

static int iCount = 1;
public synchronized void myFunct(){ 
while(iCount >= 3)
{
   try {
       wait();
   } catch (InterruptedException e) {
       e.printStackTrace();
 }

 iCount++; 

 //Do Stuffs
 //After operation decrement count

 iCount --;
 notifyAll();
}

What i am trying to do is, i want to allow only two threads to do some operation, and other threads must wait.

But here first two threads increment the count and does the operation and other threads go for an wait state but do not get the notification.

I guess i am overlooking something.

like image 296
Dheeraj Joshi Avatar asked Sep 14 '10 13:09

Dheeraj Joshi


People also ask

How do you make 2 threads run one after another?

We can use use join() method of thread class. To ensure three threads execute you need to start the last one first e.g. T3 and then call join methods in reverse order e.g. T3 calls T2. join, and T2 calls T1.

Can two threads execute at the same time?

In a multithreaded process on a single processor, the processor can switch execution resources between threads, resulting in concurrent execution. Concurrency indicates that more than one thread is making progress, but the threads are not actually running simultaneously.

Can two threads access same variable?

Only one thread can read and write a shared variable at a time. When one thread is accessing a shared variable, other threads should wait until the first thread is done.

Can two threads run at the same time in Java?

Overview. Multi-thread programming allows us to run threads concurrently, and each thread can handle different tasks. Thus, it makes optimal use of the resources, particularly when our computer has a multiple multi-core CPU or multiple CPUs.


7 Answers

Sounds like you want to use a Semaphore, you always call acquire() before doing your operation, and then release() in a finally block.

private static final Semphore semaphore = new Semaphore(2);

public static void myFunct() throws InterruptedException {
    semaphore.aquire();
    try {
        // do stuff
    } finally {
        semaphore.release();
    }
}
like image 99
Jon Freedman Avatar answered Oct 05 '22 14:10

Jon Freedman


Your function is synchronized, so only one thread at a time can be in it.

I'm not sure I understand your question... But if you want to allow two threads to go somewhere at once, have a look at Semaphore.

like image 32
Joonas Pulakka Avatar answered Oct 05 '22 15:10

Joonas Pulakka


Is this a singleton class? If not then it's a problem because many concurrent instances may change the value of icounter and in addition they will block on it forever because no thread will be able to call notify on their instance object.

Anyway you should move the sync inside the function and lock iCount and not the instance, also make it volatile.

public void myFunct(){ 
synchronized(iCount) {
while(iCount >= 3)
{
   try {
       wait();
   } catch (InterruptedException e) {
       e.printStackTrace();
 }
}
iCount++; 
}
//Do Stuffs
 //After operation decrement count
synchronized(iCount) {
 iCount--;
}
 notifyAll();
like image 27
roni bar yanai Avatar answered Oct 05 '22 13:10

roni bar yanai


Why aren't you just using a Semaphore?

like image 24
spender Avatar answered Oct 05 '22 15:10

spender


An alternative might be to use a ThreadPoolExecutor with a maximum of two threads.

like image 30
Andy Thomas Avatar answered Oct 05 '22 14:10

Andy Thomas


You need java.util.concurrent.Semaphore, initialized with 2 permits.

As for your current code - threads may cache values of variables. Try adding the volatile keyword.

like image 30
Bozho Avatar answered Oct 05 '22 13:10

Bozho


There are many problems with this code. Among them:

  1. You have no real control on the number of threads running myFunct, since the method is synchronized on the instance level, while the counter is static. So N different threads operating on N different instances may run the same method concurrently.

  2. Manipulating the counter by multiple threads is not thread safe. Consider synchronizing it or using AtomicInteger.

Regarding the limit on the number of threads, consider using the Semaphore class.

like image 34
Eyal Schneider Avatar answered Oct 05 '22 13:10

Eyal Schneider