I am at a loss. I have a BlockingDeque
private class Consumer extends Thread {
#Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
if (connection.isReady()) {
final Item item = queue.takeFirst();
try {
ListenableFuture<Result> listenableFuture = connection.submitItem(item);
Futures.addCallback(listenableFuture, new FutureCallBackImpl<Result>(item));
} catch (RejectedExecutionException e) {
LOGGER.debug("Slow down submission of tasks we have a queue full in connection");
queue.addFirst(item);
}
}
}
} catch (InterruptedException e) {
LOGGER.debug("Interrupted. I will not propagate up because I own this thread");
}
}
}
This code normally blocks at queue.takeFirst() when no items are in the queue. However, it does not unblock once I add the item as expected. While debugging I can see the items being in the queue and also when I stop Tomcat I serialize the queue. Upon starting it I de-serialize the queue and at that point the queue.takeFirst() retrieves the item (the same that previously did not retrieve) and submits it.
Does anyone have any ideas?
EDIT
To stress my point a bit more. If I change the queue.takeFirst() with a queue.pollFirst() and adjust the code slightly to ignore passes that yield null items then the code works as expected.
Perhaps your code don't enter the if because connection.isReady() returns false.
Check it to be sure that it really stops waiting for the first item in the queue.
So Let me explain why this piece of code will not work when items are added to the queue next time (i.e. after it dequeued all the elements first)
When the queue becomes empty for the first time, the call to this code final Item item = queue.takeFirst(); will throw InterruptedException, which is getting caught by code outside while loop, so the code will never return to the while loop again. Putting first try block inside while loop will resolve the first issue.
Secondly, it needed to call Thread.currentThread().interrupted() inside catch block to pass the while condition next time so that it is ready to read for future element addition into queue. Infact I didn't understand the reason for calling this line of code while (!Thread.currentThread().isInterrupted()).
Currently I am writing interesting blog for BlockingDeque (WIP), soon you will find more information at my blog http://singletonjava.blogspot.com
Related
I have a Java program. The logic is as follow:
place order out (relying on Interactive Broker / Binance API)
Once the order is filled (there will be a callback from the API), immediately execute a method called "calculateSomething"
The order is placed using Interactive Broker / Binance API. Once the order is filled, the API callback method will return a message.
The problem is that I do not know how to write out the code to identify that the order has been filled, so i can immediately execute the "calculateSomething" method with minimal waiting time.
I can think of two ways:
while loop and thread.sleep
ReentrantLock.
Method 1 works, but it's not instantaneous. Hence, I am exploring ReentrantLock and I am not sure the code is correct. Nonetheless, which method is the most efficient and can immediately execute the "calculateSomething" once the order is completed If there is a more efficient approach, please give me some help, as I have been stuck in this problem for many days.
pseudocode below.
Method 1 - thread.sleep
placeOrder(); // place order to binance <- API method
while(order is not completed){
Thread.sleep(1000)
if(order is completed){
return
}
}
calculateSomething();
Method 2 - ReentrantLock
ReentrantLock lock = new ReentrantLock();
lock.lock();
System.out.println("1. Locked");
try {
while(lock.isLocked()) {
if(isOrderCompleted() == true){
lock.unlock();
}
}
} catch(Exception e){
e.printStackTrace();
}finally {
if(lock.isLocked()) {
lock.unlock();
}
}
calculateSomething();
You can have a blocking queue.
BlockingQueue<?> finishedOrders = new ArrayBlockingQueue<>(512);
Then you have a loop that processes finished orders.
public void processFinishedOrders() throws InterruptedException{
while(!Thread.interrupted()){
finishedOrders.take();
doSomethingRelevant();
}
}
I would also suggest populating finishedOrders with a meaningful class.
BlockingQueue<Order> finishedOrders;
Order fin = finishedOrders.take();
doSomethingRelevant( fin );
That way the thread waiting on the api call can create a an order and add it to the finished orders queue, and the processing thread will have the relevant information.
EDIT: Ok, this is really stupid but I don't know why I didn't see it was a normal loop without the usual increments. I hope I was drunk when I posted this question because now I feel super idiot. Thanks anyway guys!
I'm following some tutorials on Java multi-threading in order to gather as much information and examples as possible.
On the Oracle website there is an official tutorial on Java Concurrency and I am looking at the Guarded Blocks section (here).
Whereas all the concepts are clear, I am reading the Producer/Consumer example at the bottom of the page and I do not understand some parts of the code.
Specifically, in the following is the code for the run() method of the Consumer class, where I do not understand how that for loop is supposed to work. It doesn't even look as it can work to me.
Can anyone explain me?
public void run() {
Random random = new Random();
for (String message = drop.take();
! message.equals("DONE");
message = drop.take()) {
System.out.format("MESSAGE RECEIVED: %s%n", message);
try {
Thread.sleep(random.nextInt(5000));
} catch (InterruptedException e) {}
}
}
It's just for loop being used in a non-idiomatic way.
You have the initialization String message = drop.take(); (instead of int i = 0;).
Then you have the test !message.equals("DONE"); (instead of i < 10).
Finally you have the "increment" or loop-advance or whatever the actual term is. Get the next value with message = drop.take(); (instead of i++).
Maybe it would be easier to understand when converted to a while-loop:
public void run() {
Random random = new Random();
String message = drop.take()
while (!message.equals("DONE")) {
System.out.format("MESSAGE RECEIVED: %s%n", message);
try {
Thread.sleep(random.nextInt(5000));
} catch (InterruptedException e) {}
message = drop.take()
}
}
Keep in mind that the for-loop generally consists of three parts:
for (INITIALIZATION; CONDITION; AFTERTHOUGHT)
{
// Code for the for-loop's body goes here.
}
INITIALIZATION is run once before the first iteration, CONDITION is checked prior to every iteration and AFTERTHOUGHT is executed after every iteration.
(Taken from https://en.wikipedia.org/wiki/For_loop#Traditional_for-loops)
So in this example, the INITIALIZATION of the for-loop creates the message variable and takes the first message from drop. It then checks it in the CONDITION block to see if its is anything but DONE. If it is, the loop body is executed once, printing the message and sleeping for up to 5000 milliseconds. Then the next message is taken in the AFTERTHOUGHT clause and the loops checks the CONDITION block again to either print the next message or leave the loop once it receives DONE.
This question already has answers here:
Why should wait() always be called inside a loop
(11 answers)
Closed 7 years ago.
I've tried reading some answers to similar questions here (I always do that) but did not find (or did not understand?) the answer to this particular issue.
I am implementing a fairly simple consumer-producer class, which receives elements to a list from a different thread and consumes them repeatedly. The class has the following code:
public class ProduceConsume implements Runnable
{
LinkedList<Integer> _list = new LinkedList<Integer>();
public synchronized void produce(Integer i)
{
_list.add(i);
notify();
}
public void run()
{
while(true)
{
Integer i = consume();
// Do something with the integer...
}
}
private synchronized Integer consume()
{
if(_list.size() == 0)
{
try
{
wait();
}
catch(InterruptedException e){}
return _list.poll();
}
}
}
The problem is - it usually works fine, but sometimes, the execution gets to
return _list.poll();
with the list still empty. I can't wrap my head around it - am I doing something terribly wrong? Shouldn't the runnable thread, which repeatedly tries to poll detect a zero length list, wait, and be awakened only after the producer method is done, hence making the list non-empty?
Nothing else "touches" the class from the outside, except for calls to produce. No other threads are synchronized on the runnable class.
By the way, for several reasons, I wish to use my own variant and not classes such as CopyOnWriteArrayList, etc.
Thanks! Any help would be greatly appreciated.
P.S - I have not used the wait-notify many times, but when I did, in the past, it worked. So if I apologize if I made some huge stupid error!
As the Javadoc for Object.wait states
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
Additionally, you shouldn't ignore an exception like InterruptedException. This will look like a spurious wake up and as you say produces an error.
private synchronized Integer consume() {
try {
while (_list.isEmpty())
wait();
return _list.poll();
} catch(InterruptedException e) {
throw new IllegalStateException("Interrupted");
}
}
Since wait releases the lock you can't reason based on conditions tested before it started waiting, assuming the condition must have changed once wait is exited is not valid. You need to call wait in a loop, so that once the thread ceases waiting and takes the lock again, it checks that the condition it's waiting for has the expected value:
private synchronized Integer consume()
{
try {
while (_list.size() == 0) {
wait();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return _list.poll();
}
From the Oracle tutorial:
Note: Always invoke wait inside a loop that tests for the condition being waited for.
Also it's not safe to assume that just because wait returned that something sent a notification. wait can return even if there is no notification (the spurious wakeup).
It's hard to say what caused what you're seeing without a complete working example.
The linked Oracle tutorial page has a Producer Consumer example you might want to look at.
The problem is: there are two threads, one is a writer to a List another is a reader from the List. Sometimes reader gets stuck if loop in the writer has large amount of iterations. That reader in that case becomes Blocked (not Waiting), which means that it received notification, but writer did not released monitor?
So, why so?
What is the best to do with this? (is sleep fine?)
import java.util.LinkedList;
import java.util.List;
public class Main {
private List<Object> m_calls = new LinkedList<Object>();
public void startAll(){
Thread reader = new Thread(new Runnable() {
#Override
public void run() {
while(true){
synchronized(m_calls){
while (m_calls.size() == 0) {
try {
System.out.println("wait");
m_calls.wait();
} catch (InterruptedException e) {
return;
}
}
m_calls.remove(0);
System.out.println("remove first");
}
}
}
});
Thread writer = new Thread(new Runnable() {
#Override
public void run() {
for(int i = 0; i < 15; i++){
// UN-comment to have more consistent behavior
/*try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
synchronized(m_calls){
m_calls.add(new Object());
m_calls.notifyAll();
System.out.println("sent");
}
}
}
});
reader.start();
writer.start();
}
public static void main(String[] args) {
new Main().startAll();
}
}
Running of the code above gives different results:
---------------------------------- 1st attempt
wait
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
wait
---------------------------------- 2nd attempt
wait
sent
sent
sent
sent
sent
sent
remove first
remove first
remove first
remove first
remove first
remove first
wait
sent
sent
remove first
remove first
wait
sent
sent
sent
sent
sent
sent
sent
remove first
remove first
remove first
remove first
remove first
remove first
remove first
wait
------------------------------ Uncommented sleep() - works us expected
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
Edit 1: The reader thread (one of them) seems to be not waiting any more, rather it's blocked, which looks like its monitor received notification (after notifyAll()) but writer thread do not release lock in its loop, what is confusing...
Your particular situation would be better done using a BlockingQueue. Blocking queues will block the take thread (the reader) until something is put in the queue (by a writer).
Here's your modified code using a blocking queue:
public class Main {
private BlockingQueue<Object> m_calls = new LinkedBlockingQueue<Object>();
public void startAll(){
Thread reader = new Thread(new Runnable() {
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
try {
Object obj = m_calls.take();
System.out.println("obj taken");
} catch(InterruptedException ex) {
// Let end
}
}
}
});
Thread writer = new Thread(new Runnable() {
#Override
public void run() {
try {
for(int i = 0; i < 15; i++){
m_calls.put(new Object());
System.out.println("obj put");
}
} catch (InterruptedException ex) {
// Let end
}
}
});
reader.start();
writer.start();
}
public static void main(String[] args) {
new Main().startAll();
}
}
The output:
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
This will be much safer than a) using a plain LinkedList and b) trying to use your own wait/notify. Your wait/notify was also pretty vulnerable to race conditions. If the writer thread called notify before the reader called wait, then the reader could wait indefinitely on the last entry.
I might also add that this solution is safe for multiple reader and writer threads. Multiple threads can put and take all at the same time, and the LinkedBlockingQueue will handle the concurrency for you.
The only thing to be careful about is if Object accesses some shared resource, but this is another problem that's related to concurrent access of a group of objects. (Along the lines of "can I access obj1 and obj2 at the same time from two different threads?") This is another problem entirely, so I won't detail a solution here.
Its worth nothing that nothing happens immediately and when it comes to threads, you cannot be sure when independent events happen. (Which one of the reasons synchronisation is required)
final long start = System.nanoTime();
new Thread(new Runnable() {
#Override
public void run() {
System.out.printf("Took %,d ns to start this thread%n", System.nanoTime() - start);
}
}).start();
prints
Took 2,807,336 ns to start this thread
This might not sounds like a long time, but at 3.2 GHz this is almost 9 million clock cycle. A computer can do an awful lot in that time. In your case, a short lived thread can run to completion before the second thread even starts.
In the second case, what you are seeing is that locking is not fair (i.e. fair means the one waiting the longest gets the lock first) The reason for this is it is much slower to implement this properly e.g. 10x slower or more. For this reason, a lock tends to be given the the thread which has it last as this is far more efficient in most cases.
You can get fair locks using Lock lock = new ReentrantLock(true); but this is generally not used unless required as it is slower for little gain most of the time.
You can try -XX:-UseBiasedLocking to make locking slightly fairer.
To do much the same thing with ExecutorService you can code it like
ExecutorService service = Executors.newSingleThreadExecutor();
// writer
for (int i = 0; i < 15; i++) {
service.submit(new Runnable() {
#Override
public void run() {
// reader
System.out.println("remove first");
}
});
System.out.println("sent");
}
service.submit(new Runnable() {
#Override
public void run() {
System.out.println("wait");
}
});
service.shutdown();
prints
sent
remove first
sent
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
remove first
wait
A better way to synchronize in such szenarios is to use java.util.concurrent.* in your case perhaps a CountDownLatch.
Maybe try this first before looking for a reason for the deadlock.
EDIT: And Peter is right. It seems to be running ok?
EDIT 2: OK, whole different story after the additional info.
I suggest you work with timeouts to force at least one try in reading even if there is more to write after a certain timespan.
wait even has a version with timeout ... http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#wait(long)
But again: personally I'd prefer using the concurrancy API.
I am trying to program a game in which I have a Table class and each person sitting at the table is a separate thread. The game involves the people passing tokens around and then stopping when the party chime sounds.
how do i program the run() method so that once I start the person threads, they do not die and are alive until the end of the game
One solution that I tried was having a while (true) {} loop in the run() method but that increases my CPU utilization to around 60-70 percent. Is there a better method?
While yes, you need a loop (while is only one way, but it is simplest) you also need to put something inside the loop that waits for things to happen and responds to them. You're aiming to have something like this pseudocode:
loop {
event = WaitForEvent();
RespondToEvent(event);
} until done;
OK, that's the view from 40,000 feet (where everything looks like ants!) but it's still the core of what you want. Oh, and you also need something to fire off the first event that starts the game, obviously.
So, the key then becomes the definition of WaitForEvent(). The classic there is to use a queue to hold the events, and to make blocking reads from the queue so that things wait until something else puts an event in the queue. This is really a Concurrency-101 data-structure, but an ArrayBlockingQueue is already defined correctly and so is what I'd use in my first implementation. You'll probably want to hide its use inside a subclass of Thread, perhaps like this:
public abstract class EventHandlingThread<Event> extends Thread {
private ArrayBlockingQueue<Event> queue = new ArrayBlockingQueue<Event>();
private boolean done;
protected abstract void respondToEvent(Event event);
public final void postEvent(Event event) throws InterruptedException {
queue.put(event);
}
protected final void done() {
done = true;
}
public final void run() {
try {
while (!done) {
respondToEvent(queue.take());
}
} catch (InterruptedException e) {
// Maybe log this, maybe not...
} catch (RuntimeException e) {
// Probably should log this!
}
}
}
Subclass that for each of your tasks and you should be able to get going nicely. The postEvent() method is called by other threads to send messages in, and you call done() on yourself when you've decided enough is enough. You should also make sure that you've always got some event that can be sent in which terminates things so that you can quit the gameā¦
I would look into Locks and Conditions. This way you can write code that waits for a certain condition to happen. This won't take a lot of CPU power and is even much more efficient and better performing than sleeping .
To make a thread run for an infinite time:
final Object obj = new Object();
try {
Thread th = new Thread(new Runnable() {
public void run() {
synchronized(obj) {
try {
System.out.println("Waiting");
obj.wait();
System.out.println("Done waiting");
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
});
th.start();
System.out.println("Waiting to join.");
// Dont notify; but wait for joining. This will ensure that main thread is running always.
th.join();
System.out.println("End of the Program");
} catch(Exception ex) {
ex.printStackTrace();
}
You may add Thread.sleep() with appropriate time to minimize useless loop iterations.
Another solution is using synchronization. While threads are not required to do anything, they enter into a sleeping state on a monitor using the wait() method, and then when the turn comes, required thread is woken up by the notify() method.
Actor model seems suitable for this scenario. Each person sitting on the table and the table itself can be modelled as actors and the event of passing the tokens and starting and stopping of the game can be modelled as messages to be passed between the actors.
As a bonus, by modelling the scenario as actors you get rid of explicit manipulation of threads, synchronization and locking.
On JVM I will prefer using Scala for modelling actors. For Java you can use libraries like Kilim. See this post for a comparison of Actor model related libraries in Java.
One Way is to use while loop but keep a check i.e
while(true){
if(condition!=true){
Thread.sleep(time);
}else{
break;
}
}
This way if your condition says game is not over it will keep person thread at sleep and memory consumption will be very low.
You should test for a condition in the while loop:
while (!gameOver)
{
do_intersting_stuff();
}
Heavy CPU load is typical for busy wait. Is your loop actually just checking a flag over and over, like
while (!gameOver)
{
if (actionNeeded)
{
do_something();
}
}
you might change to another notification system to sleep and wake up, as this just burns CPU time for nothing.