Win a copy of Cloud Native PatternsE this week in the Cloud forum
or Natural Language Processing in the AI/ML forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Paul Clapham
  • Knute Snortum
  • Rob Spoor
Saloon Keepers:
  • Tim Moores
  • Ron McLeod
  • Piet Souris
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Ganesh Patekar

Declare a Runnable within a Task does not work?

 
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

Because of the way I was using the ExecutorService threadpool, it was hanging the UI, so I decided to throw it into a task, but for some reason, it simply "runs" without doing anything right at the Runnable declaration. I know this is the case, because I did a System.out before and after the declaration, and the only one that shows is the one before.

Here is a basic version of what I'm trying to do. Can someone tell me why this wont work?

This is the line in question: Runnable worker = new ShowProgress("" + i);
 
Rancher
Posts: 3409
33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Could you post a small, complete program that compiles, executes and shows the problem for testing?
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Norm Radder wrote:Could you post a small, complete program that compiles, executes and shows the problem for testing?



Sure, this compiled for me and demonstrates the problem quite nicely:

 
Saloon Keeper
Posts: 10407
223
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's way too much code that's not related to the problem. Please check out this link: http://sscce.org/

Anyway, make sure you know what the execute() method does, and if that's what you intended.

I'm also not sure why you would start a separate thread just to have tasks executed by an executor service. Why are you creating task, and why are you running it in a thread?
 
Rancher
Posts: 4175
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're adding (in the second example) stuff to the Scene (via the GridPane) in a thread other than the UI thread.
This has made JavaFX unhappy.

Have a read of how to use Tasks and ProgressBars.

If you have to update the UI in the worker thread(s) then you need to use Platform.runLater.  However, you should not need to do this with a ProgressBar, if you follow the above document.
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:That's way too much code that's not related to the problem


You asked for a simplified version that can be compiled and run. I produced.

Stephan van Hulst wrote:I'm also not sure why you would start a separate thread just to have tasks executed by an executor service. Why are you creating task, and why are you running it in a thread?


Because otherwise, it freezes up the UI until the threads are done processing because of this (Which based on everything I've read, is simply what you do when you use executor):
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:You're adding (in the second example) stuff to the Scene (via the GridPane)


Yes, I want to build a form that looks at the number of threads to be executed and shows a ProgressBar for each thread (each thread does a specific number of things through a for next loop which can enumerate the ProgressBar).

Dave Tolls wrote:If you have to update the UI in the worker thread(s) then you need to use Platform.runLater.


My original code has this:

Which IntelliJ must have added for me because I didn't put it there. When I built the shortened example, the compiler was getting hung up on it, so I removed it and it worked.

Dave Tolls wrote:However, you should not need to do this with a ProgressBar, if you follow the above document.


I will read it right now.

Thank you,

Mike Sims
 
Stephan van Hulst
Saloon Keeper
Posts: 10407
223
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
An ExecutorService runs tasks for you in the background, so you don't have to create your own threads. Starting a new thread to have tasks executed by an ExecutorService makes no sense, because you're doing the job that ExecutorService is supposed to do for you. Submitting tasks to an ExecutorService takes almost no time, and will not freeze your UI.

In general, your application should have only one ExecutorService, and you should pass it to classes that need to perform tasks in the background.

In your application, make executor an instance field, and from startTasks() you can just execute the for-loop that submits all the tasks to the executor without having to use another surrounding task to do it.
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Submitting tasks to an ExecutorService takes almost no time, and will not freeze your UI.


Tell that to my application ... I tried - it's not listening.



Stephan van Hulst wrote:In your application, make executor an instance field


Which is simply executor declared at the class level and not inside a method, right?

Stephan van Hulst wrote:and from startTasks() you can just execute the for-loop that submits all the tasks to the executor without having to use another surrounding task to do it.


Sounds wonderful. Now to actually do it...

Sincerely,

Mike Sims
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:Have a read of how to use Tasks and ProgressBars.


OK, I read it ... clear as ... well ... not mud ... muddy water perhaps...

Sincerely,

Mike Sims
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan, can you please clarify something that you said for me?

Stephan van Hulst wrote:In general, your application should have only one ExecutorService, and you should pass it to classes that need to perform tasks in the background.



Ok, am I passing the ExecutorService to classes? OR Am I passing classes to the ExecutorService (presumably to have those classes executed in the background)?

Thank you,

Mike Sims
 
Stephan van Hulst
Saloon Keeper
Posts: 10407
223
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's a small example of a class that has an executor and performs tasks in the background:
 
Stephan van Hulst
Saloon Keeper
Posts: 10407
223
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Michael D Sims wrote:Ok, am I passing the ExecutorService to classes? OR Am I passing classes to the ExecutorService (presumably to have those classes executed in the background)?


Both. In the example I posted, the executor is passed to the BackgroundTaskExample class, because it needs it to run its background tasks. It passes background tasks to the executor to run.
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:the executor is passed to the BackgroundTaskExample class, because it needs it to run its background tasks. It passes background tasks to the executor to run.


Thank you for the example. It seems to make sense, I just need to play with it a little and understand it a little better.
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Here's a small example of a class that has an executor and performs tasks in the background:


OK, What if I wanted to do something like this in the run method of the PrintNumber class, where I update a ProgressBar?

When I try to pass a ProgressBar into the class, it complains that it's not running on the main application thread.
 
Stephan van Hulst
Saloon Keeper
Posts: 10407
223
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Operations on graphical components always need to be done on the Event Dispatch Thread. For JavaFX, you do that by calling Platform.runLater() and supply it a task that needs to be run on the EDT.

There's an easier way to report progress though. JavaFX has a class Task which contains a progress property. ProgressBar also has a progress property, and you can bind the two properties so ProgressBar is automatically updated when your Task makes progress.
 
Dave Tolls
Rancher
Posts: 4175
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Michael D Sims wrote:
My original code has this:

Which IntelliJ must have added for me because I didn't put it there. When I built the shortened example, the compiler was getting hung up on it, so I removed it and it worked.


That's because you didn't (at a guess) tell IntelliJ it was a JavaFX application.
That's a Swing hook for building Swing GUIs.
In any case, you still have to use runLater.
JavaFX does not like it when you do GUI stuff outside of the UI thread.
That is the root of your current lock up.

And you really should look at using the ProgressBar properly.
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:And you really should look at using the ProgressBar properly.


All I can do is Google, read and experiment ... I'm WIDE OPEN for learning. I mean ... it's not like I'm intentionally using it improperly...
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Operations on graphical components always need to be done on the Event Dispatch Thread. For JavaFX, you do that by calling Platform.runLater() and supply it a task that needs to be run on the EDT.


OK, you lost me ... EDT?

Stephan van Hulst wrote:There's an easier way to report progress though. JavaFX has a class Task which contains a progress property.


I'm VERY familiar with binding progress bar to the progressProperty. But that has to be done in a task, and the example you gave me for using an executor was specifically NOT a task. However, I seem to have massaged that class you gave me into a task that executor runs via the method you showed me ... still playing with it, but I think it's going to work. And yes, I did bind progressProperty to progress bar and I'm using the updateProgress method to update it.

:-)
 
Stephan van Hulst
Saloon Keeper
Posts: 10407
223
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Michael D Sims wrote:OK, you lost me ... EDT?


Event Dispatch Thread. In JavaFX it is also called the application thread, I believe?

I'm VERY familiar with binding progress bar to the progressProperty.


In your original code you didn't bind it though. Instead, you just set the progress on the bar directly, which is not allowed from any thread other than the EDT.

But that has to be done in a task, and the example you gave me for using an executor was specifically NOT a task.


Yes, it was just an example of how and where to use ExecutorService, not Task.

However, I seem to have massaged that class you gave me into a task that executor runs via the method you showed me ... still playing with it, but I think it's going to work.


Cool, show us what you've managed to do when you're ready.
 
Michael D Sims
Ranch Hand
Posts: 162
1
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:

Michael D Sims wrote:OK, you lost me ... EDT?


Event Dispatch Thread. In JavaFX it is also called the application thread, I believe?


Got it!

Stephan van Hulst wrote:

Michael D Sims wrote:I'm VERY familiar with binding progress bar to the progressProperty.


In your original code you didn't bind it though. Instead, you just set the progress on the bar directly, which is not allowed from any thread other than the EDT.


That was a one time thing ... don't ask...


Stephan van Hulst wrote:

Michael D Sims wrote:However, I seem to have massaged that class you gave me into a task that executor runs via the method you showed me ... still playing with it, but I think it's going to work.


Cool, show us what you've managed to do when you're ready.


I dunno ... last time I posted a real example from my code, I got lambasted .... not sure you guys with OCD could my code... lol
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!