• 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
  • Liutauras Vilda
  • Bear Bibeault
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • Devaka Cooray
Saloon Keepers:
  • Ganesh Patekar
  • Tim Moores
  • Carey Brown
  • Stephan van Hulst
  • salvin francis
Bartenders:
  • Ron McLeod
  • Frits Walraven
  • Pete Letkeman

Coding for fun - Can threads manage Threads?  RSS feed

 
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So I've taken on writing a simple chat program that listens via ServerSocket on a port, and when someone connects directly to my IP address, we can chat with one another until the cows come home... It works just fine.

What I would like to do is create a server app that clients will create a socket connection with and announce who they are etc. and if a different user wants to chat with someone who's logged in, they can do that... It's the back end that I'm not quite sure how to structure...

What makes sense to me, is to have the server listen for incoming connections, then when it senses one, it spins off a thread that is dedicated to that socket connection, handling all the ins and outs of working with the end user such as getting their name, maybe a password, and any inbound and outbound text they wish to send to and from other users who are also connected with the server on their own thread ...

Obviously I can't allow the main UI thread to sit there and listen for socket connections then spin off the threads, as that would render the UI useless ... so is it possible to have one thread spinning off other threads while maintaining communication with those threads so that it can send and receive information to and from the threads it spawned ... indefinitely?

VERY curious to see what you guys have to say about what I'm trying to do ... I've been wanting to write this app for years now and I'm finally getting the opportunity to do it.

OH and in case anyone gets tempted to tell me that I'm re-inventing the wheel and that there are plenty of free programs to do what I'm trying to do ... DON'T ... I already know this. I am writing this program strictly for the exercise and to see if I can do it.

Thank you,

Michael Sims
 
Rancher
Posts: 3276
33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

is it possible to have one thread spinning off other threads


Yes.  The communications would be via variables with access to the variables synchronized to prevent concurrent access.
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Norm Radder wrote:Yes.  The communications would be via variables with access to the variables synchronized to prevent concurrent access.


Is there a specific way of spawning those new threads that should be respected? Or can I start them just like I would from the main thread be it a Runnable, or a new Task or another instance of a class with its own thread construct ... ???

I'm thinking about this and I can't think of a situation where a variable could be written to by two threads ... if I do this properly that is ... and I'm thinking that I am going to have the "controlling thread" query the class instances looking for data and depositing data as the need occurs ...

Speaking of creating more instances of the same class and starting their threads, how does one go about that when the number of new class instances is not known? I can't very well create a new variable with a different name for each new class ... can I put them in a dynamic array somehow?  Or would I just pre-define say 100 different variables (thread1, thread2 thread3, etc.) and keep track of them and remain limited to 100 new threads???

Michael
 
Saloon Keeper
Posts: 9389
181
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All of this is very reasonable. Using threads directly is a bit old-fashioned, however. Let your main thread create an ExecutorService, which you pass to the class that's responsible for listening for incoming connections. It starts listening by submitting a task to the executor service that handles the server socket. Every time a new connection comes in, that task creates a new task to handle the connection, and submits it to the executor service. That way, the (number of) tasks that need to be performed is completely decoupled from the (number of) threads that perform them.

It would be extra nice of you don't just pass an ExecutorService to your server class, but also a task factory, that creates new tasks that handle your incoming connections. That way your server class will work not just for chat applications, but for any application that has multiple clients.
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Using threads directly is a bit old-fashioned



So I was probably in my early 30's before I ever saw the movie, "The Godfather" ... and I was born in the 1970s ... and even though by the time I actually saw it, I was a very old movie, it felt new to me ... ;-)


Stephan van Hulst wrote:however. Let your main thread create an ExecutorService, which you pass to the class that's responsible for listening for incoming connections. It starts listening by submitting a task to the executor service that handles the server socket. Every time a new connection comes in, that task creates a new task to handle the connection, and submits it to the executor service. That way, the (number of) tasks that need to be performed is completely decoupled from the (number of) threads that perform them.



See I never did get full comprehension of ExecutorService ... but maybe I should look at it again ... perhaps it'll make more sense now that I've spent more time ripping my hair out over Java ... I will say this about Java ... for being a pretty fun language to code in, I'm NOT impressed with how difficult it is doing most things GUI... For example, you'd think Java would offer some way to easily show text in different colors ... yeah not so much... Then theres the issue of just needing to have different windows (Scenes in FX) and communicating between them or even having a single Controller that oversees many windows ... there's obviously  a way to do pretty much anything in Java, but it sure can get complicated trying to do something that should be relatively simple.

Stephan van Hulst wrote:It would be extra nice of you don't just pass an ExecutorService to your server class, but also a task factory, that creates new tasks that handle your incoming connections. That way your server class will work not just for chat applications, but for any application that has multiple clients.



So these new tasks that are wrapped up in a nice Task Factory / ExecutorService package could also be useful for passing information back and forth as needed?

Michael
 
Stephan van Hulst
Saloon Keeper
Posts: 9389
181
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Michael D Sims wrote:See I never did get full comprehension of ExecutorService ... but maybe I should look at it again


An ExecutorService is simply an interface for objects that responsible for executing tasks. People tend to say that they want start a thread to do something, but that's putting the means ahead of the goal. It's like saying you want to use a hammer to install some rivets. No. You want to install rivets. Does it really matter that you want to use a hammer or a rivet gun? In this analogy, a thread is the hammer, and a task is the rivet.

Here's the outline I would use for the server code:

I will say this about Java ... for being a pretty fun language to code in, I'm NOT impressed with how difficult it is doing most things GUI...


For most people, GUI coding isn't a lot of fun regardless of the language you use. Personally, I enjoy writing GUIs in Swing, but I think using an imperative language to describe a user interface is inherently flawed. I believe JavaFX takes a more declarative approach, but I haven't worked with it before and I don't know how it "feels". These things tend to become more interesting when you have some experience with it.

So these new tasks that are wrapped up in a nice Task Factory / ExecutorService package could also be useful for passing information back and forth as needed?


Back and forth between what?
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:

Michael D Sims wrote:

I will say this about Java ... for being a pretty fun language to code in, I'm NOT impressed with how difficult it is doing most things GUI...


For most people, GUI coding isn't a lot of fun regardless of the language you use. Personally, I enjoy writing GUIs in Swing, but I think using an imperative language to describe a user interface is inherently flawed. I believe JavaFX takes a more declarative approach, but I haven't worked with it before and I don't know how it "feels". These things tend to become more interesting when you have some experience with it.

So these new tasks that are wrapped up in a nice Task Factory / ExecutorService package could also be useful for passing information back and forth as needed?


Back and forth between what?



So this is how I do Threads now ... it's simple, it's clean ... and so far, it works well for me:

 
Stephan van Hulst
Saloon Keeper
Posts: 9389
181
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why do you keep the thread in a field, and why do you create the task in a method?

Even IF you want to use a thread as opposed to using an executor service, there's usually no real need to keep track of it. Just start it and forget about it. I really recommend getting familiar with executors though, because in many application containers it is not allowed to spawn your own threads, and with good reason.

There's a cleaner way than returning a Runnable from a method. Make the method perform the task directly, and pass the method itself to the thread or executor service:

This is called a "method handle".
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Why do you keep the thread in a field, and why do you create the task in a method?

Even IF you want to use a thread as opposed to using an executor service, there's usually no real need to keep track of it. Just start it and forget about it. I really recommend getting familiar with executors though, because in many application containers it is not allowed to spawn your own threads, and with good reason.

There's a cleaner way than returning a Runnable from a method. Make the method perform the task directly, and pass the method itself to the thread or executor service:

This is called a "method handle".


This looks painful ... what is a "Future"? Some kind of an Array like a Collection?
 
Ranch Hand
Posts: 207
2
Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There's some great info in here.  Thanks
 
Stephan van Hulst
Saloon Keeper
Posts: 9389
181
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Michael D Sims wrote:This looks painful ... what is a "Future"? Some kind of an Array like a Collection?


Future represents the status and future result of a task. The task may be running, or it may have completed or not even started yet. You can find out through the Future instance. You can also use it to cancel a task. If you don't want to do any of that, you can just ignore the return value of the submit() call.
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:

Michael D Sims wrote:This looks painful ... what is a "Future"? Some kind of an Array like a Collection?


Future represents the status and future result of a task. The task may be running, or it may have completed or not even started yet. You can find out through the Future instance. You can also use it to cancel a task. If you don't want to do any of that, you can just ignore the return value of the submit() call.



I'd like to see a SIMPLE example of actually using a Future to start, monitor and kill a thread ... that might come in handy...
 
Stephan van Hulst
Saloon Keeper
Posts: 9389
181
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You don't use Future to start, monitor or kill a thread. Directly controlling threads is BAD. You use Future to control the execution of a task. For instance, when you cancel a task, it may not necessarily kill the thread, but merely return it to a thread pool.

Let's say you want to compute a number of tasks at the same time, but you only need a few of them to have finished successfully. You can do it like this:
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:You don't use Future to start, monitor or kill a thread. Directly controlling threads is BAD. You use Future to control the execution of a task. For instance, when you cancel a task, it may not necessarily kill the thread, but merely return it to a thread pool.



I read a couple of newbie tutorials on it after I posted here this morning ... I guess I need to start looking for things I code that would be better handled in this manner ... I like Runnable Threads a lot ... I'm comfortable with them ... I can't remember when I've ever used a task .... but as I think about it ... I guess what I do is I code my "tasks" as functions of my threads ... probably  a bad idea in general ... but anything I can do to get code off of the Application thread makes me happy...  I do encounter annoyances from time to time when I update my GUI with Platform.RunLater()  and I need that process to finish before the code continues ... so far I've been handling it with booleans declared at the class level, but I'm sure that's not a "best practice" ... would be a good candidate for a future?
 
Stephan van Hulst
Saloon Keeper
Posts: 9389
181
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you give a concrete example of having to wait until an update on the application thread finishes? That seems like fishy design to me.
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Can you give a concrete example of having to wait until an update on the application thread finishes? That seems like fishy design to me.



At the risk of embarrassment ... sure ...

 
Sheriff
Posts: 5300
142
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is how I learned to run a task in JavaFX without blocking the UI:
Hope that helps.
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:This is how I learned to run a task in JavaFX without blocking the UI:
Hope that helps.



Thats nice ... but in some cases, I need my code execution to STOP until the task is completes... is there a way to run the task so that it blocks until it's done?
 
Knute Snortum
Sheriff
Posts: 5300
142
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wouldn't that just be...
 
Marshal
Posts: 60867
190
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:This is how I learned to run a task in JavaFX without blocking the UI: . . .

Doesn't FX have a counterpart of SwingWorker?
 
Knute Snortum
Sheriff
Posts: 5300
142
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It seems it does, but I've haven't used it (yet).

https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Worker.html
 
Stephan van Hulst
Saloon Keeper
Posts: 9389
181
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Michael, your example doesn't contain any action that needs to wait until the UI update is done. Why do you need to wait until the text area and buttons have updated? What do you want to do afterwards?

It's also not a good idea to use polling (also known as "busy wait") to wait for other tasks to finish. I'm not convinced you need to wait at all, but if you do, use lock conditions.
 
Michael D Sims
Ranch Hand
Posts: 153
1
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Michael, your example doesn't contain any action that needs to wait until the UI update is done. Why do you need to wait until the text area and buttons have updated? What do you want to do afterwards?

It's also not a good idea to use polling (also known as "busy wait") to wait for other tasks to finish. I'm not convinced you need to wait at all, but if you do, use lock conditions.


That wasn't really the point, but I'll give you a real world example Stephan:

Here is a runnable that I want to execute as a thread to prevent the UI from hanging, lets jut assume there i a lot of code in there including blocking code such as waiting for a socket connection and as I said, I don't want the application Thread being blocked during that time - i'm not saying that is exactly what I'm doing, but just assume that is what Im doing and assume that I refuse to do it any other way ... the question still stands, is there a way to execute a Platform.runLater with blocking?:



I cannot call the showOpenDialog method outside of the Application Thread, but I need the file reference before I can continue executing the rest of the code in the Runnable, therefore, I need to block while waiting for the user to chose a file.
 
Stephan van Hulst
Saloon Keeper
Posts: 9389
181
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This illustrates nicely the reason I said your design sounded fishy. You have your background threads driving the application, while it should be the application thread driving the background threads:
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!