NullPointerException with PriorityBlockingQueue - java

I encounter a problem with using a PriorityBlockingQueue in a custom thread pull where the poll method causes a NullPointerException. When using this setup
int POOL_SIZE = 5;
int OVERHEAD_POOL_SIZE = 10;
long LIFE_TIME = 5000;
TimeUnit LIFE_TIME_UNIT = TimeUnit.MILLISECONDS;
with
new ThreadPoolExecutor(POOL_SIZE, OVERHEAD_POOL_SIZE,
LIFE_TIME, LIFE_TIME_UNIT, new PriorityBlockingQueue<Runnable>());
instead of Executors.newCachedThreadPool(), I sometimes encounter the following stack trace:
Exception in thread "pool-14-thread-3" java.lang.NullPointerException
at java.util.PriorityQueue.siftDownComparable(PriorityQueue.java:624)
at java.util.PriorityQueue.siftDown(PriorityQueue.java:614)
at java.util.PriorityQueue.poll(PriorityQueue.java:523)
at java.util.concurrent.PriorityBlockingQueue.take(PriorityBlockingQueue.java:225)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:957)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:917)
at java.lang.Thread.run(Thread.java:662)
Basically, I want to order Runnables in the queue by a priority:
class MyRunnableFuture implements
RunnableFuture<Boolean>, Comparable<MyRunnableFuture>
The wired thing is: The exception is not always thrown, but if I set a breakpoint inside of PriorityQueue.siftDownComparable, the chance for the exception to occure is higher.
Any ideas? I found other people having the same problem, but nobody really knew a solution. Do I have to synchronize the queue manually when used in a ThreadPool? I am using the queue, because I do not want to synchronize it. I understood the descriptions as if the queue was already synchronized internally? Thanks for any answers!

Updated after reading the comments below: All troubles were caused by using submit instead of execute where in the former, all threads are wrapped in a RunnableFuture internally which of course do not implement the Comparable interface. This is why the comparison failed. I got distracted by the NullPointerException which is caused when a new worker thread is trying to pull the job that could not be inserted before. (The clue: The PriorityBlockingQueue does not insert the new job because a ClassCastException is thrown. At the same time, the ThreadPoolExecutor thinks there is a new job available and alerts the next worker. The worker pulls a nonexistant job and throws a NullPointerException. The ClassCastException got swallowed and logged deep down my application, I did not trace this carefully enough since I tried to find the reason for the NullPointerException.
For the sake of completeness, the submit method of the ThreadPoolExecutor actually does the following:
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
Thanks to you guys for help (in the comments!).
PS: Mean bug.

Related

Consumer Thread and SQS - Preventing from submitting null data to the blocking queue and finding a better way to call the consumer threads at runtime

I have a standard SQS and I need to read data from it using multiple consumer threads.
To achieve the same, I have written the following method ( in Java):
public void consume() {
ExecutorService exService = Executors.newFixedThreadPool(3);
while(true) {
exService.execute(()->{
try {
/* the following code submits a null data to the blocking queue when the queue(sqs) is empty*/
OrderQ order = queueMessagingTemplate.receiveAndConvert(StringConstants.QUEUE_NAME
, OrderQ.class);
if(order!=null)
repstiory.saveOrder(order);
log.debug("Received from queue:"+ order);
}catch(Exception exc) {
log.error("couldn't read msg from queue");
throw new CouldNotReadMessageFromSQSException("couldn't read msg from queue");
}
});
}
}
and, as of now, I have two approaches to call the above method and start consuming the messages from the queue stated as follows along with the issues associated with them:
Approach-1 :
create a rest api and call this method. This approach won't work in production and also when the queue is empty, null will keep getting populated in the blocking queue of the thread pool. So, this is clearly not a good approach. Question-How can I ensure that only 'not null' data is submitted to the blocking queue?
Approach-2:
calling the consume method from CommandLineRunner but the issue is, the queue, most probably, won't have data as soon as the application starts and will run into the same problem as described in the 1st approach.
Problem-1:What can be a better solution to handle the null data problem?
problem-2:what can be better way to call the consume method, considering the production environment?
Kindly suggest solutions and best practices to achieve the same.

Java - Callable Out of memory solution?

Hi Guys can you help me about the error that I've encountered on my Java program. I do the Callable implementation with a loop, Basically I need to send a request to another webservice and I will be collecting the response ID. Based on my testing, my aim to process it asynchronously is working using the below implementation. One time I try to run again my program then I got this kind of error "Error 500: java.lang.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 11". What I did is I just restarted the server then it becomes ok.
So I want to know if there is something wrong with my implementation? like is there any additional line of code that I need to add or remove just to prevent again to experience those kind of error? I only experience it once. Hope you could help me
//pccsSurvList is a list of details coming from the database.
ExecutorService executorService = null;
List<Callable<SyncFlagEntity>> lst = new ArrayList<Callable<SyncFlagEntity>>();
if(pccsSurvList != null && pccsSurvList.size() > 0){
executorService = Executors.newFixedThreadPool(pccsSurvList.size());
for(PCCSSurveyInfoEntity user: pccsSurvList){
NotifyEmailTransactionImpl emailTransact = new NotifyEmailTransactionImpl(user);
lst.add(emailTransact);
}
}
// returns a list of Futures holding their status and results when all complete
List<Future<SyncFlagEntity>> tasks = new ArrayList<Future<SyncFlagEntity>>();
tasks = executorService.invokeAll(lst);
executorService.shutdown();
java.lang.OutOfMemoryError: Failed to create a thread
This OutOfMemoryError indicates that Java is out of memory.
Most likely the problem lies on this line ...
executorService = Executors.newFixedThreadPool(pccsSurvList.size());
You are getting a lot of rows and there's no enough RAM for the JVM to create a thread for each one. Try logging the number of rows you get and see what's happening.
I think you are running too many processes at once. You should try to set a limit and use a thread pool.
Maybe you can do something like:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(pccsSurvList.size());
Then inside for loop you can do:
executor.submit(() -> emailTransact);
There is more here: https://www.baeldung.com/thread-pool-java-and-guava
Also take a look at reactive programming. Can be of more help in your case: https://www.vogella.com/tutorials/RxJava/article.html

How to use FallbackFuture to handle TimeoutException?

I have my task and fallback for it:
ListenableFuture<T> listenableAsyncTask = executorService.submit(asyncTaskCallable);
ListenableFuture<T> listenableFallbackTask = executorService.submit(fallBackTaskCallable);
From them, I form a fail tolerant ListenableFuture:
ListenableFuture<T> failTolerantListenableFuture = Futures.withFallback(listenableAsyncTask, new FutureFallback<T>() {
#Override
public ListenableFuture<T> create(Throwable t) throws Exception {
return listenableFallbackTask;
}
});
And I have a list of fail tolerant futures:
List<ListenableFuture<T>> listenableFutures = ...;
It's time to get the result, in a certain amount of time:
result = Futures.allAsList(listenableFutures).get(50,TimeUnit.MILLISECONDS);
At this point, I expect that if a task failed to finish within 50ms, the return output will be handled by the fallBackTask, which is a lightweight one.
But not as I planed, I got the following exception:
java.util.concurrent.TimeoutException: Timeout waiting for task.
Which causes me losing all results from other succeed tasks. It seems that the fallback didn't work in this case for me. Or I misunderstood the concept?
We need to distinguish between "the Future fails" and "the call to Future.get fails."
"The Future fails" if the task you submitted throws an exception. (For purposes of withFallback, we also consider cancellation to be a failure. That's not relevant here, though, and the behavior may change someday.)
"The call to Future.get fails" if any of the following happen:
the Future fails
the call times out
the call is interrupted
withFallback handles only the case in which the Future fails, without handling cases of timeout or interruption.
If your goal is to retrieve all the primary results that are done within 50 milliseconds, with all other cases falling back to the secondary results, you can try something like this, which uses withTimeout to automatically fail the Future after a given timeout:
List<ListenableFuture<T>> originalFutures = ...;
List<ListenableFuture<T>> defaultAfterTimeoutFutures = new ArrayList<>();
for (ListenableFuture<T> f : originalFutures) {
f = Futures.withTimeout(f, 50, MILLISECONDS, executor);
f = Futures.withFallback(f, ...);
defaultAfterTimeoutFutures.add(f);
}
result = Futures.allAsList(defaultAfterTimeoutFutures).get();
But note that that last get call may wait longer than 50 milliseconds: If a primary Future fails, then the get call must wait until its fallback is done. If you don't want to wait for the fallbacks, then you will need to wrap them with withTimeout, as well. And if you do wrap them, then they will fail after the timeout, at which point allAsList will also fail. If you don't want that, then you'll need to either use successfulAsList (instead of allAsList) or wrap the wrappers with withFallback again, this time with a value that is always available immediately.

Java Thread: Run method cannot throw checked exception

In Java thread, the 'run' method cannot throw a 'checked exception'. I came across this in the Core Java (vol 1) book. Can someone please explain the reasoning behind it?
Can someone please explain the reasoning behind it?
Yes, because any exception you throw in run method will be carefully ignored by JVM. Thus, throwing it there is probably a mistake (unless you have specific exception handler for the thread, see the docs about that). No reason to incite potentially erroneous behaviour.
Or, with an example.
class MyThread extends Thread {
public void run() {
throw new RuntimeException();
}
}
...
new MyThread().start();
// here thread dies silently with no visible effects at all
edit
Why can't the parent thread 'catch' the exception from the spawned 'child' thread?
#chaotic3quilibrium has already noted in his comment why not: because parent thread has likely moved on already.
new MyThread().start(); // launch thread and forget
// 1000 lines of code further...
i = i + 1; // would you like exception from child thread to be propagated here?
What would catch the exception and handle it? Let's assume that the run method could throw a checked exception. Then you could write code like this:
Thread myThread = new Thread(aRunnable);
try{
myThread.start();
}
catch(Exception e){
e.printStackTrace();
}
//do other stuff
BUT once you call myThread.start, the new thread is started in the background and the current thread continues and exits the try-catch and does other stuff. So if myThread did throw an exception later on, you can't catch it!
What you need to do is deal with the exception within the run method and then probably have a way of notifying another object that this thread failed.
Suppose thread A starts up thread B. Then thread B throws an exception. You might think it would be nice for thread A to catch it. But where? By the time thread B thows the exception, who knows what thread A is doing? To take a trivial example, suppose we have this code in thread A:
try
{
threadB=new PurgeAbandonedCarts();
threadB.start();
}
catch (NullPointerException panic)
{
... handle errors purging abandoned carts ...
}
try
{
processNewOrders();
}
catch (NullPointerException panic)
{
... handle problems in new orders ...
}
finally
{
... clean up ...
}
So we start up thread B to purge abandoned carts. Once it gets starte, we move on to processing new orders. Then thread B throws a null pointer exception. Should it be caught by the catch block associated with thread B, or the one associated with processing new orders?
If it goes to the new orders catch, it's likely that any code here has nothing to do with cleaning up problems with thread B. That can't be the right answer.
If you say the one associated with thread B, then that means that during the processing of new orders, control could suddenly be yanked out and sent back to try thread B catch block. But then what happenned to processing new orders? Do we just stop in the middle? Do we not even hit the finally block? And when we're done, do we then just keep executing and fall through to processing new orders again? Do we process orders twice? This can't be the right answer either.
Thus, there is nowhere to go if run throws an exception. The only logical thing to do is to have the run method catch any exceptions thrown itself, and handle them within the new thread.
throws declarations are part of the methods signature. To allow checked exceptions for Runnable#run, one had to declare them on the Runnable interface and had to try/catch everytime we start a thread.
Then again, we usually don't call the run method, we just implement it. We start() a Thread and then, somehow, the run method is called.
But the most obvious reason: When we start threads, we usually don't want to wait until the run method terminates just to catch exceptions like this:
try {
new Worker().start(); // now wait until run has finished
} catch (SomeThreadException oops) {
// handle checked exception
}
The reason is that exception is thrown back to the caller. Caller of run() method is not your code. It is the Thred itself. So even if run() throws exception the program cannot catch it.
You should put thread execution result to some class level variable and then read it from there. Or alternatively use new API: executors and interface Callable that declares method call() that returns future result of the thread execution.
The more obvious solution to the previous answers is that if you throw a checked exception, you are not correctly implementing run() as specified in the runnable interface.
It won't even compile:
run() in TestClass cannot implement run() in java.lang.Runnable;
overridden method does not throw java.lang.Exception

How to terminate CXF webservice call within Callable upon Future cancellation

Edit
This question has gone through a few iterations by now, so feel free to look through the revisions to see some background information on the history and things tried.
I'm using a CompletionService together with an ExecutorService and a Callable, to concurrently call the a number of functions on a few different webservices through CXF generated code.. These services all contribute different information towards a single set of information I'm using for my project. The services however can fail to respond for a prolonged period of time without throwing an exception, prolonging the wait for the combined set of information.
To counter this I'm running all the service calls concurrently, and after a few minutes would like to terminate any of the calls that have not yet finished, and preferably log which ones weren't done yet either from within the callable or by throwing an detailed Exception.
Here's some highly simplified code to illustrate what I'm doing already:
private Callable<List<Feature>> getXXXFeatures(final WiwsPortType port,
final String accessionCode) {
return new Callable<List<Feature>>() {
#Override
public List<Feature> call() throws Exception {
List<Feature> features = new ArrayList<Feature>();
//getXXXFeatures are methods of the WS Proxy
//that can take anywhere from second to never to return
for (RawFeature raw : port.getXXXFeatures(accessionCode)) {
Feature ft = convertFeature(raw);
features.add(ft);
}
if (Thread.currentThread().isInterrupted())
log.error("XXX was interrupted");
return features;
}
};
}
And the code that concurrently starts the WS calls:
WiwsPortType port = new Wiws().getWiws();
List<Future<List<Feature>>> ftList = new ArrayList<Future<List<Feature>>>();
//Counting wrapper around CompletionService,
//so I could implement ccs.hasRemaining()
CountingCompletionService<List<Feature>> ccs =
new CountingCompletionService<List<Feature>>(threadpool);
ftList.add(ccs.submit(getXXXFeatures(port, accessionCode)));
ftList.add(ccs.submit(getYYYFeatures(port accessionCode)));
ftList.add(ccs.submit(getZZZFeatures(port, accessionCode)));
List<Feature> allFeatures = new ArrayList<Feature>();
while (ccs.hasRemaining()) {
//Low for testing, eventually a little more lenient
Future<List<Feature>> polled = ccs.poll(5, TimeUnit.SECONDS);
if (polled != null)
allFeatures.addAll(polled.get());
else {
//Still jobs remaining, but unresponsive: Cancel them all
int jobsCanceled = 0;
for (Future<List<Feature>> job : ftList)
if (job.cancel(true))
jobsCanceled++;
log.error("Canceled {} feature jobs because they took too long",
jobsCanceled);
break;
}
}
The problem I'm having with this code is that the Callables aren't actually canceled when waiting for port.getXXXFeatures(...) to return, but somehow keep running. As you can see from the if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted"); statements the interrupted flag is set after port.getFeatures returns, this is only available after the Webservice call completes normally, instead of it having been interrupted when I called Cancel.
Can anyone tell me what I am doing wrong and how I can stop the running CXF Webservice call after a given time period, and register this information in my application?
Best regards, Tim
Edit 3 New answer.
I see these options:
Post your problem on the Apache CXF as feature request
Fix ACXF yourself and expose some features.
Look for options for asynchronous WS call support within the Apache CXF
Consider switching to a different WS provider (JAX-WS?)
Do your WS call yourself using RESTful API if the service supports it (e.g. plain HTTP request with parameters)
For über experts only: use true threads/thread group and kill the threads with unorthodox methods.
The CXF docs have some instructions for setting the read timeout on the HTTPURLConnection:
http://cwiki.apache.org/CXF20DOC/client-http-transport-including-ssl-support.html
That would probably meet your needs. If the server doesn't respond in time, an exception is raised and the callable would get the exception. (except there is a bug where is MAY hang instead. I cannot remember if that was fixed for 2.2.2 or if it's just in the SNAPSHOTS right now.)

Categories

Resources