File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes ArrayBlockingQueue's poll method creates selfish thread Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "ArrayBlockingQueue Watch "ArrayBlockingQueue New topic
Author

ArrayBlockingQueue's poll method creates selfish thread

Derik Davenport
Ranch Hand

Joined: May 30, 2011
Posts: 57
I have a serial I/O monitor thread. that parses data form a serial port. This (low level) thread works by calling Thread.sleep(10) then waking up to check for the existence of data. If it finds none, it immediately sleeps again. When data arrives, it is parsed in that thread. If it is found to be complete and proper it is published by dropping a copy of the data into an ArrayBlockingQueue object.

I have a second, (high level) thread monitoring that same ArrayBlockingQueue for completed messages.

If my high level thread calls , then I get one of 2 behaviors (Windows XP Java 6u34)

1. If a completed message is already waiting on the queue, then the poll method returns immediately. No problem.
2. If no message is on the queue, the call to poll will wait the full 500ms and then return null. Nearly instantaneously thereafter, the (low level) serial monitor thread will get a time slice from the JVM, discover a completed message, and place it on the queue.

Now I know for a fact that if the remote device on the serial port responds at all it is guaranteed to happen within 200ms and usually within 20ms. So this means that for 300+ms, there was data waiting, but the serial monitor thread was not acting on this data. This seems to be because the call to poll is a selfish thread which prevents other thread from running. To test that theory I replaced the call above with the following loop.



This seems to completely fix my problem. Typically within a few tens of milliseconds, the low level serial monitor thread will receive data; and the high level thread monitoring the ArrayBlockingQueue will see the data almost immediately thereafter. But I have nagging doubts about this solution because of some unanswered questions.

Shouldn't the Windows XP version of the JVM use time slicing to ensure that the poll statement is not selfish?
Is using the poll function in a non-selfish loop like the one above the only way to safely use the poll method? If so, why would carefully crafted concurrent package create a blocking function that is potentially a selfish thread?



Just for your reference, If you look that source code for the method in java.util.concurrent.ArrayBlockingQueue, you will find the following code.



The call to notEmpty.awaitNanos relies on code found in a method of the same name of a ConditionObject object. In turn, ConditionObject is a public inner class of java.util.concurrent.locks.AbstractQueuedSynchronizer.


Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18825
    
  40

Derik Davenport wrote:
Shouldn't the Windows XP version of the JVM use time slicing to ensure that the poll statement is not selfish?
Is using the poll function in a non-selfish loop like the one above the only way to safely use the poll method? If so, why would carefully crafted concurrent package create a blocking function that is potentially a selfish thread?



Windows XP supports preemptive timeslicing. Furthermore, there is even logic to prevent thread starvation that bumps the effective priority of lesser ran threads .... so what you are describing should never happen !!


*AND* also...

Derik Davenport wrote:
Just for your reference, If you look that source code for the method in java.util.concurrent.ArrayBlockingQueue, you will find the following code.



The call to notEmpty.awaitNanos relies on code found in a method of the same name of a ConditionObject object. In turn, ConditionObject is a public inner class of java.util.concurrent.locks.AbstractQueuedSynchronizer.


As you pointed out, threads waiting for data uses condition variables -- the concurrent library replacement for the wait/notify mechanism -- which means that the thread is not in a runnable state when it is waiting. Only runnable threads can run, so the thread could not be scheduled at all.


Don't know what the issue is ... but there is definitely something else going on here.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2285
    
  49
Rather than the high level thread being selfish it is more likely that the low level thread is being blocked from running in some way. Can you show the code for your low level thread. Are you using synchronized blocks anywhere or any other forms of locks?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: ArrayBlockingQueue's poll method creates selfish thread