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

Experimenting with Concurrency

 
Bartender
Posts: 1679
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Anticipating needing to have a responsive UI, I found some code on the Internet that creates a task and lets me do other stuff (when you click the button).

Yet, ever after I added the "setOnCloseRequest", the thread the program creates doesn't get cancelled after the program window exits.

Not sure where to put what code to kill the thread that's created.

This code may have other issues, but it seems to work OK. I converted two cases to use Lambdas instead of Anon. Inner Classes.

Thanks in advance on how to kill the created and still running thread (or suggestions for a better multi-threading starting point.

mike

------

 
Ranch Hand
Posts: 374
24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
> how to kill the created and still running thread

For the example you give, you don't really need an ExecutorService, you could just create a new thread directly and run your task on that.  By setting your new thread to daemon using thread.setDaemon(true), the thread will automatically stop on shutdown regardless of whatever it is doing.  If all it is doing is pausing and requesting deferred UI updates through runLater which you have in your example, a daemon thread is fine.  If it is doing something persistent like writing to a database or a file, then a daemon thread is not good and instead proper cancellation logic should be implemented to ensure that the thread does not exit until the required atomic operations are completed.

So for me, all I would normally do is this:

No explicit shutdown request required.  This is also mentioned in the JavaFX Task javadoc.

----

In your code, you haven't really explicitly created a thread.  Instead you have delegated the thread management to an ExecutorService.  Because the threads created are managed by the ExecutorService, tell the ExecutorService to shutdown and it will try to co-ordinate with any threads you created to shut them down.  The documentation for ExecutorService provides some advice on shutting it down, I suggest you read that.  Normally I'd just use the Executors factory methods to create an ExecutorService (if I needed one, which you may not).

To explicitly shutdown an ExecutorService defined in a JavaFX program, add a stop() method to your application and shutdown the ExecutorService there:

Cancelling tasks running on other threads is a co-operative process.  Just because you want the task to stop and send a signal to it, doesn't mean it will immediately stop.  The task itself should be coded to be aware that it can get a cancellation signal and appropriately handle it.  For information on how to accomplish this read both the JavaFX Task documentation which talks about cancellable tasks as well as this article by Brian Goetz: https://www.ibm.com/developerworks/library/j-jtp05236/ (the section titled "Implementing Cancelable Tasks").  The key is to have the task check if it has been cancelled or the thread it is running on has been interrupted.  From the Task doc (full doc has examples as well):

In Java there is no reliable way to "kill" a thread in process. However, when cancel is called on a Task, it is important that the Task stop processing. A "run-away" Task might continue processing and updating the message, text, and progress properties even after the Task has been cancelled! In Java, cancelling a Task is a cooperative endeavor. The user of the Task will request that it be cancelled, and the author of the Task must check whether is has been cancelled within the body of the call method. There are two ways this can be done. First, the Task author may check the isCancelled method, inherited from FutureTask, to see whether the Task has been cancelled. Second, if the Task implementation makes use of any blocking calls (such as NIO InterruptibleChannels or Thread.sleep) and the task is cancelled while in such a blocking call, an InterruptedException is thrown. Task implementations which have blocking calls should recognize that an interrupted thread may be the signal for a cancelled task and should double check the isCancelled method to ensure that the InterruptedException was thrown due to the cancellation of the Task.

 
Mike London
Bartender
Posts: 1679
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wow, such great information, thank you!!!

I bought the "Learn Java FX 8" book since the bartender here is also reading it, but it doesn't seem to cover how to control threads cooperatively - say with a consumer / producer or other synchronization model.

I was thinking about writing a "file search" utility. On the mac, as you may know, there is not a single file search utility that uses regular expressions. The mac search utilities mostly, lazily, rely on the Spotlight index. That's great unless you're searching for something not in the index. Using File Locator Pro (on Windows) as an example (the best file search program I've ever seen and the only program to make me miss Windows, a little), I would try to start 4 threads. I don't see that these threads would need to be synchronized since they would be working on separate files.

In any case, that code I posted above was just an example I found on the Internet. I too would keep the thread code much simpler.

Thank you very much for your help!!!

Look forward to any replies.

- mike
 
John Damien Smith
Ranch Hand
Posts: 374
24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
> bartender here is also reading it, but it doesn't seem to cover how to control threads cooperatively - say with a consumer / producer or other synchronization model.

Bartenders are the world's greatest multi-taskers :-)

> I was thinking about writing a "file search" utility.   The mac search utilities mostly, lazily, rely on the Spotlight index. That's great unless you're searching for something not in the index.

I'm not an expert in search, but my guess is that is usually best to search based upon an index.
I would be hesitant to write my own search algorithms or utilities for something like file search.
I would attempt to use existing libraries to help with this, for example
 http://lucene.apache.org
 http://lucene.apache.org/solr/
 https://www.elastic.co

>  I would try to start 4 threads. I don't see that these threads would need to be synchronized since they would be working on separate files.

Yeah, search is something which you can partition and run in parallel.  
Fork/Join can be used if needed:
 https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
As can parallel streams:
 https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html
 
Mike London
Bartender
Posts: 1679
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, the Mac index is totally amazing. If you remember the old days where there was a DOS program called "Norton Magellan" where there was a disk indexing program too.

A couple problems with the mac Spotlight index come to mind:

1. Not all files are indexed.

This means some file types like ".gz", some 'zip, and many, many Windows files just aren't searched at all.

2. You can't use RegEx to search.

This is a big one.

-----

If you look at File Locator Pro (mythicsoft.com) as an example, there is NOTHING even approaching this program on the Mac.  So, I keep a VM, sadly, just to run FLP for complete searches. Share Mac folders and use FLP.  FLP has so many excellent options, I can't believe that Mac has NOTHING like it. Spotlight is excellent and "enough" for most users. But professional users, programmers, and other may be disappointed with basically no alternatives. (Yes, there are "free/basic" programs that don't rely on the Spotlight index, like "EasyFind", but it misses files too and does not support RegEx. Hasn't been updated in a long time, etc.).

----

- mike

 
Marshal
Posts: 65002
246
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know whether things are different for JavaFX, but it would be dangerous to create multiple threads in Swing. Cai Horstmann says it has never been possible to make a thread‑safe GUI framework that executes faster than a half‑dead snail. You have one thread and one only that accesses the display. If you are doing something time‑consuming, which searching a hard drive would be, you can start a worker thread which does all the searching completely independently from the display.
 
Mike London
Bartender
Posts: 1679
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I don't know whether things are different for JavaFX, but it would be dangerous to create multiple threads in Swing. Cai Horstmann says it has never been possible to make a thread‑safe GUI framework that executes faster than a half‑dead snail. You have one thread and one only that accesses the display. If you are doing something time‑consuming, which searching a hard drive would be, you can start a worker thread which does all the searching completely independently from the display.



That's funny.

AFAIK, you can just start as many threads as you want, within reason, in FX.

I would envision, as a test, a user entering four file names and I would search them using four threads.

Since FX is not based on AWT, that may help.

- mike
 
John Damien Smith
Ranch Hand
Posts: 374
24
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I don't know whether things are different for JavaFX, but it would be dangerous to create multiple threads in Swing. Cai Horstmann says it has never been possible to make a thread‑safe GUI framework that executes faster than a half‑dead snail. You have one thread and one only that accesses the display. If you are doing something time‑consuming, which searching a hard drive would be, you can start a worker thread which does all the searching completely independently from the display.


It is the same in JavaFX.  
See the information on threads in the Glass Windowing Toolkit section of the JavaFX architecture overview:
 https://docs.oracle.com/javase/8/javafx/get-started-tutorial/jfx-architecture.htm#A1107438

That doesn't mean that you can't write multi-threaded JavaFX programs using JavaFX.  You just need to make sure that anything which effects the active scene graph (properties of nodes which are currently in a displayed scene), is only modified on the JavaFX application thread.  But anything which is not directly effecting the active scene graph (including modifications to nodes that not part of the active scene graph) can be written in its own thread.  

JavaFX does provide some helper facilities which allow you to do stuff such as perform I/O or calculations on other threads (such as the file search algorithms proposed by Mike) and then communicate the results of those operations back to the JavaFX thread for updating of the UI on the JavaFX thread.  

Those mechanisms are the Task/Service concurrency facilities:
 https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm
 https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html
 https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Service.html
And the runLater method:
 https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable-
The task javadoc does a very good job of documenting and providing examples of writing multi-threaded operations that interoperate with the JavaFX application thread.  Note that the examples are very careful to compartmentalize work so that the active scene graph is not touched by non-JavaFX threads.

Background reading:
 https://community.oracle.com/blogs/kgh/2004/10/19/multithreaded-toolkits-failed-dream
Coding efficiently for chips like this http://arstechnica.com/gadgets/2016/12/amd-zen-performance-details-release-date/ can be challenging for problem domains that are not immediately amenable to divide and conquer strategies.
 
Mike London
Bartender
Posts: 1679
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Great info.

I think I would still be OK if I just used the file names from four text boxes and then started four threads to read those files?

Those threads when say, finding a search term in any of the four files, would then update text field type controls with matching text found, so maybe not a good FX threading scenario?

This is confusing.

Maybe Java FX isn't what I should be using for this project?

Thanks,

- mike
 
John Damien Smith
Ranch Hand
Posts: 374
24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
> This is confusing.

Multi-threaded programming is more complicated than single threaded programming - that is just the way it is.
All modern UI toolkits are single-threaded in nature, so you have to deal with these kind of concurrent programming issues, no matter what toolkit you use.
Java has very good concurrency support.  The base synchronization/notification/monitor stuff is a bit older, but you don't need to use that, as the high level constructs in java.util.concurrent and javafx.concurrent can accomplish all of those kind of tasks using more intuitive higher level constructs.
There are other languages which are built from the ground-up for concurrency support, such as GO or Erlang.  And there are Actor model based concurrency systems such as in the Scala libraries.  But those languages and libraries don't generally have good UI toolkits associated and integrated with their in-built concurrency mechanisms.

For what you are doing, implementing in Java doesn't seem overly complicated to me.  You don't need to use all of the advanced libraries in the java.util.concurrent package.  You can stick to very simple constructs, just use the javafx.concurrent.Task and (if necessary the Platform.runLater calls).  Run your search processing logic on daemon threads executing a JavaFX task and just have the Tasks return the search results.
For UI development, farming long running work and I/O out to worker threads and communicating the result back through an asynchronous return mechanism is the standard way of development.  Literally everything you need to know to develop the concurrent aspects of your application is probably already documented in the Task javadoc.

> Maybe Java FX isn't what I should be using for this project?

There are of course other options, but whatever you choose probably won't be simpler for developing apps with concurrent features.  So I wouldn't use concurrent app development simplicity as a reason for choosing one runtime platform over another.  More important issues are usually around ease of deployment, ability to deploy to target OSes, ease of integrating with in-built features of desktop and mobile environments, use of native vs UI toolkit rendered controls, etc.

> I think I would still be OK if I just used the file names from four text boxes and then started four threads to read those files?
> Those threads when say, finding a search term in any of the four files, would then update text field type controls with matching text found, so maybe not a good FX threading scenario?

Seems like a perfectly reasonable scenario to me.
 
Mike London
Bartender
Posts: 1679
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Man, you REALLY know this stuff.

Thanks!!!

- mike
 
Campbell Ritchie
Marshal
Posts: 65002
246
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

John Damien Smith wrote:. . . That doesn't mean that you can't write multi-threaded JavaFX programs using JavaFX.  You just need to make sure that anything which effects the active scene graph (properties of nodes which are currently in a displayed scene), is only modified on the JavaFX application thread.  But anything which is not directly effecting the active scene graph (including modifications to nodes that not part of the active scene graph) can be written in its own thread.   . . .

That “own thread” sounds like a worker thread, so the situation sounds just the same as in Swing.
 
Campbell Ritchie
Marshal
Posts: 65002
246
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

John Damien Smith wrote:. . . You don't need to use all of the advanced libraries in the java.util.concurrent package.  You can stick to very simple constructs . . .

What a good idea.
The amount of work you have put into this thread merits a cow.

You might find your posts look better with the quote button rather than > symbols. Just a suggestion.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!