I have looked at similar threads but did not get a satisfactory reply.
In the JMS receiver thread, I see a while loop coded as follows:
while(true)
{
Thread.sleep(1000);
}
The above thread also has a registered listener attached to it, which implements the messageListener interface and thus provides for the the callback onMessage() event.
When the onMessage() event gets triggered on the listener, what happens to the receiver thread?
Does its state become false? Does it get interrupted (and throws an interrupted exception)?
What exactly happens at the while loop stated above?
The code above is simply saying 'wait forever' - it most likely is a hastily designed way of NOT ending this thread before someone hits Ctrl-C. The code of while(true) will always be true, so it just blocks here until this thread is interrupted. There is no magic inside this thread !
However in your second (invisible) 'message dispatcher thread' that has been automatically created in Connection.start() messages are received and dispatched to your onMessage() method. Until you call Connection.stop() or your exit your program.
Related
quarkus reactive uses mutiny to handle task asynchronously.
But, the flow is always wait every job to finish, then returns the result.
Sometime, I just want to trigger a job and let it run in the background without waiting it to be done.
Any suggestion or example?
Uni<Integer> mainJob() {
// fake logic
return Uni.createFrom().item(1);
}
Uni<Void> sideJob(int n) {
// fake logic
logger.log("result = " + n);
}
#Path("test")
Uni<Integer> testExample() {
return mainJob().onItem().call(n -> sideJob(n));
}
The upper code only returns after sideJob() is done. But, I just want to return the result immediately once mainJob is done, with sideJob triggered and run in background.
Any suggestion on it?
ManagedExecutor may be a way to do but it seems not natural in this case. The side job may/not be long running.
According to the Uni interface documentation:
To trigger the computation, a UniSubscriber must subscribe to the Uni. It will be notified of the outcome once there is an item or failure event fired by the observed Uni. A subscriber receives (asynchronously) a UniSubscription and can cancel the demand at any time.
Thus, the only way to start the execution of a Uni is by subscribing to it, even by calling uni.await().indefinitely() you are, in fact, subscribing to the Uni as we can see in the documentation of the indefinitely() method:
Subscribes to the Uni and waits (blocking the caller thread) indefinitely until a item event is fired or a failure event is fired by the upstream uni.
Invoking the call() method is nothing more than chaining a new function that will be included in the stream that will be executed when the Uni is subscribed. This way, when the testExample() method returns the result of the call(), it is not executing and waiting for the Uni to finish, it is actually returning the result immediately.
However, whoever is going to receive the final result must wait for the Uni stream to finish, so the client waiting for the HTTP response will be waiting for the sideJob() to finish in order to receive the original value, but once again, your testExample() method is not waiting for anything, it returns the Uni immediately without waiting for it to be executed.
I was trying to stop the SqsMessageDrivenChannelAdapter when calling stop() I was receiving the following error:
java.util.concurrent.TimeoutException: null
at java.util.concurrent.FutureTask.get(FutureTask.java:205)
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.stop(SimpleMessageListenerContainer.java:197)
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.doStop(SimpleMessageListenerContainer.java:133)
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.stop(AbstractMessageListenerContainer.java:329)
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.stop(SimpleMessageListenerContainer.java:1)
at org.springframework.integration.aws.inbound.SqsMessageDrivenChannelAdapter.doStop(SqsMessageDrivenChannelAdapter.java:140)
at org.springframework.integration.endpoint.AbstractEndpoint.stop(AbstractEndpoint.java:111)
First indications I thought it was a time out was not long enough, after looking into the issue I found the stopping thread and the running thread are waiting for each other and the TimeoutException would always happen. I fixed this by the follow piece of code:
new Thread() {
public void run()
{
sqsMessageRawDataChannelAdapter.stop();
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(5));
}
}.start();
I now no longer get the TimeoutException as the thread is able to stop. Have I done something wrong, or is this an issue?
M-m-m. Looks like a deadlock in your code.
You try to stop an adapter (and therefore listener) from thread which is held by the listener.
In your terms stopping thread == running thread.
To avoid such a problem you definitely should shift the stop operation to different Thread.
Does anyone know why WaitForSingleObject() or WaitForMultipleObjects() would return ERROR_IO_PENDING where the object i'm waiting on is an event created with CreateEvent()?
In my testing i've tried WFSO and WFMO, manual and auto, INFINITE and 5000, and as soon as I call WaitFor* I get immediately back ERROR_IO_PENDING.
What on earth can be pending about an event object? The point of them is that you wait on them. This event is not part of an OVERLAPPED and nothing to do with an IO call. It is just being used as a one-shot flag for my worker thread to exit (which is SetEvent()ed by another thread).
So - question is - ERROR_IO_PENDING coming back from WFSO - and ideas?
Rich
i am building an application for clients to get questions from server and answer it, if the server doesn't have questions i want to go to new screen and print message that try again in few minutes, getting questions is in AsyncTask , if the server doesn't have questions , it will sends in the header of the responds, a header isFindAQuestion with the value false, here is the code on client to ensure if false , i print on LogCat and i see the message = false, but my problems that even if i start new activity with the intent, this activity keep working and show me exception and it is null pointer exception because on the onPostExceute will take a parmeter null and try to process it, i put finish() in the end of false statement but doesn't finish the activity
if (response.getFirstHeader("isFindAQuestion").getValue()
.toString().equals("false")) {
Log.d("message", "false");
Bundle basket = new Bundle();
basket.putString("Message", "sorry no enought questions");
Intent goToAnswerQuestion = new Intent(AnswerQuestion.this,
FinishTime.class);
goToAnswerQuestion.putExtras(basket);
startActivity(goToAnswerQuestion);
finish();
}
Editis it because AsyncTask is working on thread so if the activity is finished, that thread will keep working? and if so how can i stop that thread?
doInBackground is not executed in the UI thread, but in a separeted thread:
invoked on the background thread immediately after onPreExecute()
finishes executing. This step is used to perform background
computation that can take a long time.
If you want to stop your background operation and perform some activities on the UI thread the better thing is to call cancel() and then perform all the stuff you want in the onCancelled callback wich is executed on the UI thread.
From the AsyncTask documentation:
A task can be cancelled at any time by invoking cancel(boolean).
Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns.
To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)
protected void onCancelled (Result result)
Runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished.
The default implementation simply invokes onCancelled() and ignores the result. If you write your own implementation, do not call super.onCancelled(result).
According to MSDN:
The WaitForSingleObject function can wait for the following objects:
Change notification
Console input
Event
Memory resource notification
Mutex
Process
Semaphore
Thread
Waitable timer
Then we can use WaitForSingleObject to make the parent-thread wait for child ones.
int main()
{
HANDLE h_child_thread = CreateThread(0,0, child, 0,0,0); //create a thread in VC
WaitForSingleObject(h_child_thread, INFINITE); //So, parent-thread will wait
return 0;
}
Question
Is there any other way to make parent-thread wait for child ones in VC or Windows?
I don't quite understand the usage of WaitForSingleObject here, does it mean that the thread's handle will be available when the thread terminates?
You can establish communication between threads in multiple ways and the terminating thread may somehow signal its waiting thread. It could be as simple as writing some special value to a shared memory location that the waiting thread can check. But this won't guarantee that the terminating thread has terminated when the waiting thread sees the special value (ordering/race conditions) or that the terminating thread terminates shortly after that (it can just hang or block on something) and it won't guarantee that the special value gets ever set before the terminating thread actually terminates (the thread can crash). WaitForSingleObject (and its companion WaitForMultipleObjects) is a sure way to know of a thread termination when it occurs. Just use it.
The handle will still be available in the sense that its value won't be gone. But it is practically useless after the thread has terminated, except you need this handle to get the thread exit code. And you still need to close the handle in the end. That is unless you're OK with handle/memory leaks.
for the first queation - yes. The method commonly used here is "Join". the usage is language dependant.
In .NET C++ you can use the Thread's Join method. this is from the msdn:
Thread* newThread = new Thread(new ThreadStart(0, Test::Work));
newThread->Start();
if(newThread->Join(waitTime + waitTime))
{
Console::WriteLine(S"New thread terminated.");
}
else
{
Console::WriteLine(S"Join timed out.");
}
Secondly, the thread is terminated when when you are signaled with "WaitForSingleObject" but the handle is still valid (for a terminated thread). So you still need to explicitly close the handle with CloseHandle.