Threads in JDK 1.8 - multithreading

We have a Multithreaded application that was working fine in jdk 1.7. After we upgraded to Jdk 1.8, one of our threads stopped working as expected. The call method for this thread is at the bottom of this post/question.
It seems like the thread stays in runnable state and is not selected by the JVM to run for some reason. However if we uncomment "The Statement" in the below code everything works. My assumption is that without this line the JVM thinks that the thread is not doing anything and therefore does not select this thread to run. Is this true? What can we do to solve this besides placing dummy code to print something.
public String call() {
String result = "";
try {
while (!SomeClass.singleton.isDone()) {
//The Statement - Everything works if you uncomment below statement
//System.out.println("Status : " + elapsed);
elapsed = (System.currentTimeMillis() - startTime) / 60000;
// check the max job run time.
if (elapsed > SomeClassProperties.singleton().getMaxRunTime()) {
System.out.println("MaxRunTime exceeded. Killing job.");
SomeClass.singleton.killJob();
}
// don't log status until we've discovered the payload count
if (SomeClass.singleton.getPayloadsFound() < 1)
continue;
System.out.println("Status : " + elapsed);
logErrorMessages();
Thread.sleep(30000);
}
}
catch(Exception e){
//Do Something
}
}

Unless I miss my guess, your thread goes into a heavy non-switching endless loop due to the while condition being true, and the if-condition before "continue" staying false.
The System.out implicitly yields the thread, therefore your other threads have a chance to get some cpu time.
Thus, try inserting
Thread.yield()
or
Thread.sleep(someSmallTimeInterval)
in your if-continue block.

Related

How can I update progress bar without blocking UI? [duplicate]

This question already has answers here:
How do I update the GUI from another thread?
(47 answers)
Closed 1 year ago.
Currently I am creating a background STA thread to keep the UI responsive but it slows down my function calls on the main thread.
Based on this thread How to update progress bar while working in the UI thread I tried the following but the UI only gets updated after all of the work has finished. I tried playing around with the Dispatcher priorities but none of them seem to work.
What I also tried is adding _frmPrg.Refresh() to my Progress callback but this does not seem to change anything.
Dim oProgress = New Progress(Of PrgObject)(Sub(runNumber)
_frmPrg.Invoke((Sub()
_frmPrg.Status = runNumber
End Sub))
End Sub)
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(Sub()
DoLongRunningWork(oProgress, _cancellationToken)
End Sub, System.Windows.Threading.DispatcherPriority.Background)
I can't really help you with your problem, but I'll try to clarify what happens in your posted code.
DoLongRunningWork will be invoked through Dispatcher on the UI thread, when the UI thread is not busy. But once started, it will block the UI thread until it completes. So you can't show a progress this way. Your single chance is, to let DoLongRunningWork run on a background thread. That brings you nothing, if the long-running methods come from office objects, which must be accessed from the UI thread...
The Progress class (see the remarks section) invokes your event handler on the UI thread automatically, so you don't need _frmPrg.Invoke in your event handler.
Maybe you can start a STAthread for your progress form and show it from there. The instance of your Progress class must be created in this thread too, but not before your form is shown to ensure, that the thread becomes a WindowsFormsSynchronisationContext (or you set one explicitly after starting the thread). A plain SynchronisationContext won't work!
At least you get updates in your form this way, but the UI thread of the office app will still be blocked. And of course, any action you make with your progress form must be invoked on the UI thread, if accessing office objects.
After reading some other posts, I decided to suggest another solution. My previous answer still contains usable information, so I'll leave it there. I'm not familiar with VB.NET syntax, so the samples are in C#. I have tested the code in a VSTO plugin for PowerPoint, but it should run in any office application.
Forget the Progress class and background threads. Run everything on the UI thread!
Now use some async code. To stay on the UI thread, we need a "good" SynchronizationContext.
private static void EnsureWinFormsSyncContext()
{
// Ensure that we have a "good" SynchronisationContext
// See https://stackoverflow.com/a/32866156/10318835
if (SynchronizationContext.Current is not WindowsFormsSynchronizationContext)
SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
}
This is the event handler of a button. Note the manually added async keyword. The SynchronizationContext.Current gets resetted again and again, so ensure the good one in the EventHandler:
private async void OnButtonClick(object sender, EventArgs e)
{
EnsureWinFormsSyncContext();
// Return from event handler, ensure that we are really async
// See https://stackoverflow.com/a/22645114/10318835
await Task.Yield();
await RunLongOnUIThread();
}
This will be the worker method, also running on the UI thread.
private async Task RunLongOnUIThread()
{
//Dummy code, replace it with your code
var pres = addIn.Application.Presentations.Add();
for (int i = 0; i < 100; i++)
{
Debug.Print("Creating slide {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId);
// If you have some workloads that can be run on a background
// thread, execute them with await Task.Run(...).
try
{
var layout = pres.Designs[1].SlideMaster.CustomLayouts[1];
var slide = pres.Slides.AddSlide(i + 1, layout);
var shape = slide.Shapes.AddLabel(Microsoft.Office.Core.MsoTextOrientation.msoTextOrientationHorizontal, 0, 15 * i, 100, 15);
shape.TextFrame.TextRange.Text = $"Text on slide {i + 1}";
}
catch (Exception ex)
{
Debug.Print("I don't know what am I doing here, I'm not familiar with PowerPoint... {0}", ex);
}
// Update UI
statusLabel.Text = $"Slide {i + 1} done";
progressBar1.Value = i + 1;
// This is the magic! It gives the main thread the opportunity to update the UI.
// It also processes input messages so you need to disable unwanted buttons etc.
await IdleYield();
}
}
The following method is for Windows Forms Applications where it does the job perfect. I've tried it also in PowerPoint. If you are facing problems, try the WPF flavour with await Dispatcher.Yield(DispatcherPriority.ApplicationIdle) instead of await IdleYield().
private static Task IdleYield()
{
var idleTcs = new TaskCompletionSource<bool>();
void handler(object s, EventArgs e)
{
Application.Idle -= handler;
idleTcs.SetResult(true);
}
Application.Idle += handler;
return idleTcs.Task;
}
Here are the (clickable) links to the answers that I used (I can't put them in the code-blocks...).
Incorrect async/await working, Excel events in Excel Application Level Add-in
When would I use Task.Yield()?
Task.Yield - real usages?
If in your real code something runs not as expected, check the thread you are running on and SynchronizationContext.Current.

Kotlin: Why isn't job.invokeOnCompletion() block running on main thread?

In my Android application I have code that should run periodically in its own coroutine and should be cancelable.
for this I have the following functions:
startJob(): Initializes the job, sets up invokeOnCompletion() and starts the work loop in the respective scope
private fun startJob() {
if (::myJob.isInitialized && myJob.isActive) {
return
}
myJob= Job()
myJob.invokeOnCompletion {
it?.message.let {
var msg = it
if (msg.isNullOrBlank()) {
msg = "Job stopped. Reason unknown"
}
myJobCompleted(msg)
}
}
CoroutineScope(Dispatchers.IO + myJob).launch {
workloop()
}
}
workloop(): The main work loop. Do some work in a loop with a set delay in each iteration:
private suspend fun workloop() {
while (true) {
// doing some stuff here
delay(setDelayInMilliseconds)
}
}
myJobCompleted: do some finalizing. For now simply log a message for testing.
private fun myJobCompleted(msg: String) {
try {
mainActivityReference.logToGUI(msg)
}
catch (e:Exception){
println("debug: " + e.message)
}
}
Running this and calling myJob.Cancel() will throw the following exception in myJobCompleted():
debug: Only the original thread that created a view hierarchy can touch its views.
I'm curious as to why this code isn't running on the main thread, since startJob() IS called from the main thread?
Furthermore: is there a option similar to using a CancellationTokenSource in c#, where the job is not immediately cancelled, but a cancellation request can be checked each iteration of the while loop?
Immediately breaking off the job, regardless of what it is doing (although it will pretty much always be waiting for the delay on cancellation) doesn't seem like a good idea to me.
It is not the contract of Job.invokeOnCompletion to run on the same thread where Job is created. Moreover, such a contract would be impossible to implement.
You can't expect an arbitrary piece of code to run on an arbitrary thread, just because there was some earlier method invocation on that thread. The ability of the Android main GUI thread to execute code submitted from the outside is special, and involves the existence a top-level event loop.
In the world of coroutines, what controls thread assignment is the coroutine context, while clearly you are outside of any context when creating the job. So the way to fix it is to explicitly launch(Dispatchers.Main) a coroutine from within invokeOnCompletion.
About you question on cancellation, you can use withContext(NonCancellable) to surround the part of code you want to protect from cancellation.

Why do my blocking Futures not run on single core?

When I run the following (simplified) code on a low powered server with only 1 core:
implicit val context: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global
Future(blocking {
while (true) {
java.lang.Thread.sleep(1000)
println("thread 1")
}
})
while (true) {
java.lang.Thread.sleep(1000)
println("main")
}
Only "main" shows up in the logs. If I increase the server to have more cores, then it works. What am I doing wrong? How to make Scala/Java run every thread even when there are limited cores?
My understanding is that the runtime should use some logic to execute one thread for a bit, then switch to the other thread.
scalaVersion := "2.12.12"
After a bit of playing around, I found that if I use ExecutionContext.fromExecutor(Executors.newFixedThreadPool(30)) for my EC it works. So something about the way I understand the global EC & blocking must be wrong.
I am not able to replicate this problem. Even on a single core there should be at least one thread available when using ExecutionContext.global because the default calculations is
numThreads = Runtime.getRuntime.availableProcessors * 1
and so
Future(blocking {
while (true) {
java.lang.Thread.sleep(1000)
println("thread 1")
}
})
should execute in that thread whilst
while (true) {
java.lang.Thread.sleep(1000)
println("main")
}
should execute in the main thread.
Note even with just a single thread available, if you consistently used blocking {} then new threads would still be spawned up to maxExtraThreads
scala.concurrent.context.maxExtraThreads = defaults to "256"
Hence the problem likely lies somewhere else.

Using thenAccept after supplyAsync blocks the main thread

I am developing a web application which communicates with other web applications. From time to time, my system sends HTTP request as notification to other systems. Since their responses are not essential to me, I send the requests with Java 8 CompletableFuture supplyAsync and prints their responses with thenAccept so that my main thread will not get blocked. However, I found the CompletableFuture function chains took around 100 to 200 ms each time, which confused me because from my understanding thenAccept() should run in the same thread with supplyAsync()'s.
I mocked my process with below codes
public static void run() {
long start = System.currentTimeMillis();
log.info("run start -> " + new Timestamp(start));
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 42;
}).thenAccept(res -> log.info("run result -> " + res + ", time -> " + new Timestamp(System.currentTimeMillis())));
log.info("run duration ->" + (System.currentTimeMillis() - start));
}
public static void runAsync() {
long start = System.currentTimeMillis();
log.info("runAsync start -> " + new Timestamp(start));
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 42;
}).thenAcceptAsync(res -> log.info("runAsync result -> " + res + ", time ->" + new Timestamp(System.currentTimeMillis())));
log.info("runAsync duration ->" + (System.currentTimeMillis() - start));
}
public static void main(String[] args) throws InterruptedException {
Test.run();
Test.runAsync();
Thread.sleep(1000);
}
the run() method uses thenAccept() with supplyAsync() while runAsync() uses thenAcceptAsync(). I expected both of them should take just a few milliseconds. However, the real outputs are:
10:04:54.632 [main] INFO Test - run start -> 2017-12-08 10:04:54.622
10:04:54.824 [main] INFO Test - run duration ->202
10:04:54.824 [main] INFO Test - runAsync start -> 2017-12-08 10:04:54.824
10:04:54.826 [main] INFO Test - runAsync duration ->2
10:04:55.333 [ForkJoinPool.commonPool-worker-1] INFO Test - run result -> 42, time -> 2017-12-08 10:04:55.333
10:04:55.333 [ForkJoinPool.commonPool-worker-3] INFO Test - runAsync result -> 42, time ->2017-12-08 10:04:55.333
We can see run() takes 202 ms which is 100 times of the duration of runAsync() which uses only 2 ms.
I don't understand where is the 202 ms overhead comes from, and obviously it is not the lambda function in supplyAysnc() which sleeps 500 ms.
Could anyone explain why the run() method blocks, and should I always use thenAcceptAsync() over thenAccept() ?
Many thanks.
…because from my understanding thenAccept() should run in the same thread with supplyAsync()'s
Your understanding is wrong.
From the documentation of CompletableFuture:
Actions supplied for dependent completions of non-async methods may be performed by the thread that completes the current CompletableFuture, or by any other caller of a completion method.
The most obvious consequence is that when a future is already completed, the function passed to thenAccept() will be evaluated directly in the caller’s thread, as the future has no possibility to command the thread which completed it. In fact, there is no association of a CompletableFuture with a thread at all, as anyone could call complete on it, not just the thread executing the Supplier you passed to supplyAsync. That’s also the reason why cancel does not support interruption. The future doesn’t know which thread(s) could potentially try to complete it.
The not so obvious consequence is that even the behavior described above is not guaranteed. The phrase “or by any other caller of a completion method” does not restrict it to the caller of the completion method registering the dependent action. It could also be any other caller registering a dependent action on the same future. So if two threads are calling thenApply concurrently on the same future, either of them could end up evaluating both functions or even weirder, each thread could end up executing the other thread’s action. The specification does not preclude it.
For the test case you have provided in your question, you are more likely to measure the initial­ization overhead, as described in this answer. But for the actual problem in your web application where the framework will be initialized only once, you’re likely stumbling over the wrong under­standing of thenApply’s behavior (or any non-async chaining method in general). If you want to be sure that the evaluation does not happen in the caller’s thread, you must use thenApplyAsync.
The 200 ms are startup time for the thread pool and all the classes supporting it.
It becomes obvious if you swap the statements in your main class:
public static void main(String[] args) throws InterruptedException {
Test.runAsync();
Test.run();
Thread.sleep(1000);
}
now Test.runAsync(); is the call that needs 200 ms and Test.run(); completes in 2 ms

Kill Spring scheduled thread

Is there anyway to timeout a scheduled task (kill thread) in Spring if the task takes to long or even hangs because of remote resource unavailability
In my case, tasks can take too long or even hang because they're based on HtmlUnitDriver (Selenium) sequence of steps, but from time to time it hangs and I would like to be able to set a time limit for the thread to execute. Something like 1 minute at most.
I setup a fixed rate execution of 5 minutes with an initial delay of 1 minute.
Thanks in advance
I did the same some time ago following this example: example
The basic idea is to put your code in a class implementing Callable or Runnable, then create a FutureTask wherever you are going to invoque your thread with the Callable or Runnable class as parameter. Define an executor , submit your futureTask to the executor, and now you are able to execute the thread for x time inside a try catch block, if your thread ends with an timeoutException you will know that it took too long.
Here is my code:
CallableServiceExecutor callableServiceExecutor = new CallableServiceExecutor();
FutureTask<> task = new FutureTask<>(callableServiceExecutor);
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(task);
Boolean exito = true;
try {
result = task.get(getTimeoutValidacion() , TimeUnit.SECONDS);
} catch (InterruptedException e) {
exito = false;
} catch (ExecutionException e) {
exito = false;
} catch (TimeoutException e) {
exito = false;
}
task.cancel(true);
executor.shutdown();
See: How to timeout a thread
The short answer is that there is not easy or reliable way to kill a thread due to the limitations of Java's thread implementation. The ExecutorService#shutdown() is sort of a hack and heavy. Its best to deal with this in the task itself e.g. like at the network request level if your making a REST request to timeout on the socket.
Or better if you do some sort of message passing ala Actor model (see Akka) you can send a message from "supervisor" for the Actor to die. Also avoiding blocking by using something like Netty will help.

Resources