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.
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.
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.
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.
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.
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();
}
}
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.
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();
Why aren't you just using a Semaphore?
An alternative might be to use a ThreadPoolExecutor with a maximum of two threads.
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.
There are many problems with this code. Among them:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With