I followed the advice I found in this post using CountDownLatch and i'm running into a problem. I wrote up this test and ran it and my thread I created blocks when i try to synchronize on lock.
private CountDownLatch lock = new CountDownLatch(1);
#Test
public void testBlock() {
Runnable r = new Runnable() {
#Override
public void run() {
try
{
synchronized(this) {
this.wait(50);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
throw (new RuntimeException(e));
}
releaseLock();
}
};
Thread t = new Thread(r);
t.setDaemon(true);
t.start();
waitOnCallback();
}
private void releaseLock() {
synchronized(lock) { // Thread t blocks here
lock.countDown();
}
}
private void waitOnCallback() {
synchronized(lock) {
try
{
lock.await();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
Why isn't this working?
A CountDownLatch is not an object on which you need to synchronize (i.e. remove the synchronized(lock) blocks). all thread-safety is handled internally to the object itself.
Related
I am new to Multithreading, I am trying to Synchronize multiple request coming to method addRequestToPool,
New instance is created every time of class TicketRequestManagement and method addRequestToPool is called which will create thread and call further.
But it looks like when there are multiple request to addRequestToPool method which will further call synchronizeRequests the thread is not synchronized 2 thread will enter the code block instead of below synchronization code.
synchronized (this) {
while (hashMap.containsKey(docketNo)) {
wait();
}
hashMap.put(docketNo,1);
}
Below is the complete code
TicketRequestManagement :
public class TicketRequestManagement {
private static Logger logger = Logger.getLogger(TicketRequestManagement.class);
public SimpleActionResponse addRequestToPool(int docketNo) throws InterruptedException {
logger.info("addRequestToPool started with Docket No : " + docketNo);
SimpleActionResponse response = new SimpleActionResponse();
RequestSynchronization requestSynchronization = new RequestSynchronization(docketNo);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
requestSynchronization.synchronizeRequests();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t1.join();
return response;
}
public SimpleActionResponse removeRequestFromPool(int docketNo) throws InterruptedException {
logger.info("removeRequestFromPool started with Docket No : " + docketNo);
SimpleActionResponse response = new SimpleActionResponse();
RequestSynchronization requestSynchronization = new RequestSynchronization(docketNo);
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
requestSynchronization.removeRequests();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t2.start();
t2.join();
return response;
}
}
RequestSynchronization :
public class RequestSynchronization {
private static Logger logger = Logger.getLogger(RequestSynchronization.class);
private static ConcurrentHashMap<Integer, Integer> hashMap = new ConcurrentHashMap<>();
private int docketNo;
public RequestSynchronization(int docketNo) {
super();
this.docketNo = docketNo;
}
public void synchronizeRequests() throws InterruptedException {
synchronized (this) {
while (hashMap.containsKey(docketNo)) {
wait();
}
hashMap.put(docketNo,1);
}
}
public void removeRequests() throws InterruptedException {
synchronized (this) {
hashMap.remove(docketNo);
notify();
}
}
}
Can you please suggest what is the thing I am doing wrong here and I would also like to know the scope of variable docketNo for each request coming will it remain sync with it's thread even after it goes to wait or there is some effect on it.
Thank you in advance !!
Edit 1 :
I have changed my access level to class level Locking and sending class instance instead of docket Number, below is my Modified method code but it looks like notify is not working now don't know why :(
private final static Object lock = new Object();
public synchronized static void synchronizeRequests(RequestSynchronization requestSynchronization) throws InterruptedException {
while (hashMap.containsKey(requestSynchronization.getDocketNo())) {
lock.wait();
}
hashMap.put(requestSynchronization.getDocketNo(), requestSynchronization.getDocketNo());
}
public synchronized static void removeRequests(RequestSynchronization requestSynchronization) throws InterruptedException {
hashMap.remove(requestSynchronization.getDocketNo());
lock.notifyAll();
}
Below is the consumer producer problem code, but the code is not working as expected. Here the consumer and producer are supposed to be just producing and consuming one object.
public class ProducerConsumer {
private static LinkedList<Integer> linkedList = new LinkedList<>();
public static void main(String a[]) throws InterruptedException {
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized(this) {
while (linkedList.size() == 1) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized(this) {
while (linkedList.isEmpty()) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
We get the output as : Produced
And the program hangs.
Please help with possible solutions/ explanations
Use a shared lock. In the posted code each Runnable is using itself as a lock so no actual locking takes place.
When a thread waits, another thread needs to call notify on the same lock in order to wake up the waiting thread. We know from your logging that the Producer thread does its thing, but since the notify acts on a lock that is not the same as the one the Consumer is using, the consumer thread never wakes up.
Changing the code to use a shared lock works:
import java.util.*;
public class ProducerConsumer { private static LinkedList linkedList = new LinkedList();
public static void main(String a[]) throws InterruptedException {
final Object lock = new Object();
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
while (linkedList.size() ==1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized (lock) {
while (linkedList.isEmpty()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
Output for this is:
c:\example>java ProducerConsumer
Produced
Consumed
which I think is what you're expecting.
Btw see this other answer I wrote for a dirt-simple implementation of a queue; you are better off protecting the shared data structure than putting the code in the threads accessing the data structure, especially look at how much easier the code is to write.
Concurrency means that you can not know before runtime which Thread will end first. So you can not know which of the Consumer and Producer is launched, executed or finished first.
To help you, you can use a cyclic barrier https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html or applying the Fork/Join Framework https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
Your synchronized blocs just say : only one Thread at a time can execute this part of code, not execute the first and the second after.
An example of how CyclicBarrier works :
service = Executors.newFixedThreadPool(numThreadsTotal);
CyclicBarrier c = new CyclicBarrier(numThreadsToWait);
runProducer();
c.await();
runConsumer();
It will wait until the there is as much Threads as numThreadsToWait that have execute the runProducer to execute the runConsumer().
Perhaps using a Thread Pool with a size of 1 could help you, but you will loose the benefits of concurrency.
I think best what you can do, is use BlockingQueue.
I am trying to do it using two threads like below. Can someone point the obvious mistake I am doing here?
public class OddEven {
public static boolean available = false;
public static Queue<Integer> queue = new LinkedList<Integer>();
static Thread threadEven = new Thread() {
#Override
public void run() {
printEven();
}
public synchronized void printEven() {
while (!available) {
try {
wait();
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
System.out.println(queue.remove());
available = false;
notifyAll();
}
};
static Thread threadOdd = new Thread() {
#Override
public void run() {
printOdd();
}
public synchronized void printOdd () {
while (available) {
try {
wait();
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
System.out.println(queue.remove());
available = true;
notifyAll();
}
};
public static void main(String[] args) {
int n = 20;
for (int i = 1; i < n; i++) {
queue.add(i);
}
threadOdd.start();
threadEven.start();
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
threadOdd.join();
threadEven.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
But this program is only printing 1 and quitting. After printing 1 the available should be true and printEven should wake up, print and set available to false. I don't understand what is going wrong here? I saw other solutions but want to know why my solution is not working.
Putting synchronized on an instance method means that the thread calling that method has to acquire the lock on that instance; public void synchronized printOdd() is syntax sugar for
public void printOdd() {
synchronized(this) {
...
}
}
where this is different for each instance, since ThreadOdd and threadEven are two different objects and each one uses its own lock. The methods notifyAll and wait are called on the object that is being used as the lock. When one thread waits it never gets notified because the notification only applies to other threads waiting on the same lock as the notifying thread.
class firstThread extends Helper1
{
Thread thread_1 = new Thread(new Runnable()
{
#Override
public void run() {
try {
for (int i = 1; i <= 20; i++) {
System.out.println("Hello World");
Thread.sleep(500);
if (i == 10) {
Notify();
Wait();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class secondThread extends firstThread
{
Thread thread_2 = new Thread(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
Wait();
for(int i = 1; i<=20; i++)
{
System.out.println("Welcome");
Thread.sleep(100);
}
Notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class Helper1
{
public synchronized void Wait() throws InterruptedException
{
wait();
}
public synchronized void Notify() throws InterruptedException
{
notify();
}
}
public class InheritanceClass {
public static void main(String[] args)
{
Thread f = new Thread(new firstThread().thread_1);
Thread s = new Thread(new secondThread().thread_2);
f.start();
s.start();
}
}
Only the first Thread has an output. Please try my code. I don't know why it happens.
The second thread does not give output, I suppose it's because of Wait() in the secondThread, I don't know what to do.
The problem is with the following code:
class Helper1
{
public synchronized void Wait() throws InterruptedException
{
wait();
}
public synchronized void Notify() throws InterruptedException
{
notify();
}
}
Above, the wait() and notify() calls are equivalent to this.wait() and this.notify(). However, thread1 and thread2 are separate objects so they are not ever going to communicate via this method.
In order for communication to occur, you need a shared lock object. For example:
Object lock = new Object();
firstThread = new firstThread(lock);
secondThread = new secondThread(lock);
and synchronizations like:
void wait(Object lock) {
synchronized(lock) {
lock.wait();
}
}
void notify(Object lock) {
synchronized(lock) {
lock.notify();
}
}
Disclaimer: I would never do this personally, however it does answer the OP's question.
This code is really confusing, which is making it hard to see the underlying problem.
You should never start a class with a lower-case letter since it makes it look like a method/field name (e.g. firstThread).
I'm pretty sure Wait and Notify have no reason to be synchronized.
Why does secondThread inherit from firstThread??? Actually, why do you have those two classes at all? You should just make an anonymous inner class from Helper1 or something.
Anyway, the problem is that when you call Notify() in thread1 it notifies itself, not thread2.
Sorry if the question is quite simple. I am a beginner.
I have to create thread that calulates something, while the first thread works the other one have to measure if the first thread calculate the function in specified time. If not, it has to throw exception. Else it returns the answer.
I'd take the java.util.concurrent components - simple example
public void myMethod() {
// select some executor strategy
ExecutorService executor = Executors.newFixedThreadPool(1);
Future f = executor.submit(new Runnable() {
#Override
public void run() {
heresTheMethodToBeExecuted();
}
});
try {
f.get(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// do something clever
} catch (ExecutionException e) {
// do something clever
} catch (TimeoutException e) {
// do something clever
}
}
Have your thread notify a synchronization object when it is done and have your other thread wait x number of milliseconds for it to finish.
public class Main {
private static final Object mThreadLock = new Object();
static class DoTaskThread extends Thread {
public void run() {
try {
int wait = new Random().nextInt(10000);
System.out.println("Waiting " + wait + " ms");
Thread.sleep(wait);
} catch (InterruptedException ex) {
}
synchronized (mThreadLock) {
mThreadLock.notifyAll();
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
synchronized (mThreadLock) {
DoTaskThread thread = new DoTaskThread();
thread.start();
try {
// Only wait 2 seconds for the thread to finish
mThreadLock.wait(2000);
} catch (InterruptedException ex) {
}
if (thread.isAlive()) {
throw new RuntimeException("thread took too long");
} else {
System.out.println("Thread finished in time");
}
}
}
}
join is a lot simpler than using a lock.
join (millis)
Waits at most millis milliseconds
for this thread to die. A timeout of 0
means to wait forever.
Example code:
Thread calcThread = new Thread(new Runnable(){
#Override
public void run() {
//some calculation
}
});
calcThread.start();
//wait at most 2secs for the calcThread to finish.
calcThread.join(2000);
//throw an exception if the calcThread hasn't completed.
if(calcThread.isAlive()){
throw new SomeException("calcThread is still running!");
}
Have a look at http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination(long,%20java.util.concurrent.TimeUnit) which allows you to handle this without dealing with thread synchronization yourself.