aspose file tools*
The moose likes Threads and Synchronization and the fly likes Methods for threads? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Methods for threads?" Watch "Methods for threads?" New topic
Author

Methods for threads?

Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Hi to all, I've a conceptual problem with threads.
I'm building a multi-threaded program which structure is already defined: many threads in many different places, one server and some terminals. But any class is implemented as a Runnable and so any object is a Thread. A thread has not only the run methos but many other methods for controlling his behaviour (for example the server threas has many methods for server's functions).
Then at a certain point during the execution the program blocks, in my opinion is a synchronization problem but I'm not sure. Do you think I need to rethink about the overall structure? Is a thread meant to run only the main method or it can have other methods?

Thank you in advance!
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

Can you rephrase your question? I understand you have a deadlock problem, but that's about it. Can you be more explicit in what you want?
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Sorry, I know my question was a bit confused.
Let's start from a "basic" question: Can a thread have other methods to control his behaviour or it should have only the run method? For example can I create a Thread "magazine" that has two methods: one or adding an item and one for removing an item? I can do it practically but is it correct from a theoretical point of view?
Ranganathan Kaliyur Mannar
Bartender

Joined: Oct 16, 2003
Posts: 1076
    
  10

First of all, a class being Runnable doesn't make it a Thread. Only when an instance of that class is created and passed to create a new Thread object, you get a Thread. And still, the Thread doesn't start until the start() method on that instance is called.
(Also, technically you can create instances of those classes and call methods without creating a Thread - but that indicates poor design).

Marco Zanini wrote: Can a thread have other methods to control his behaviour or it should have only the run method?


Of course you can have several other methods other than run() in the Thread. Normally, if my Thread does lot of stuff, I will have them in seperate methods and call those methods from within the run() method.

However, if you are talking about invoking those methods outside of the run() method, that means that particular Thread doesn't call those methods. You are propably calling those methods from main thread or some other thread - again, not right way of doing things.


Ranga.
SCJP 1.4, OCMJEA/SCEA 5.0.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Exactly! I know that to make a Thread I have to call the Thread class and pass the Runnable object, it was just to make you understand which method I use for creating Threads.

In the main program the Thread is started and then its methods are called from outside, calling methods of the Runnable item. As I thought, this is a wrong way of doing things. Which method should I prefer? Just create simple classes?
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

Well, your example is flawed. A magazine is not a Thread. It's also not a Runnable. A magazine sounds like it could be some data structure which you can then perform operations on in some external thread, but it makes no logical sense for it to be a thread or even a runnable itself.

Forget the entire Thread class for a moment. If you set up your program properly, you don't even have to use it. The Runnable interface is useful for modeling "tasks". A task is a set of operations which together take a certain amount of time, and which can be performed concurrently with other tasks. You perform tasks on data structures. Tasks can be handled by executor services.

Now, why do you think you need more than one thread in your program?
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Ok, as I thought: threads only for tasks. I'm using threads only because I have to develop the program based on a pre-existent structure.

Many thanks
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

What kind of application is this, and what is it based on that uses so many threads?
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
It's a client-server program where the server has to copy and execute some commands on remote computers, looking for changes (busy waiting) on a specific directory on the server and propagate changes. There can be many clients, and many remote computers to execute commands on.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

You mean like a file synchronization service?

Note that you don't have to poll for directory changes anymore. Java 7 provides the WatchService class.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Yes, like a file synchronization service. But I also have to transfer files via FTP and execute some commands so I use Jsch.

Yes I'm using the WatchService but do I need to implement a cycle to look for notifications on the keys?
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

Well, if a client needs to notify the server of changes to a directory, all it needs is a loop that calls the take() method on a WatchService continuously, and then send the result to the server. This is not a busy wait, because the take() method blocks until a change is available. You can do this in the main thread of the client application, or in a separate Runnable that you pass to an ExecutorService.
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

Ranganathan Kaliyur Mannar wrote:However, if you are talking about invoking those methods outside of the run() method, that means that particular Thread doesn't call those methods. You are propably calling those methods from main thread or some other thread - again, not right way of doing things.

I beg to differ. There can be legitimate reasons of having other methods in a Runnable implementation, which may be invoked from outside the class, in some other thread. One common example is a method to alter the state of this Runnable instance in such a manner which signals the related thread to stop gracefully.

Basically, there can be any number of methods in such a class which may, most commonly, either alter the state to send a signal to the run method, or return the state of this class as altered by the run method.
Ranganathan Kaliyur Mannar
Bartender

Joined: Oct 16, 2003
Posts: 1076
    
  10

Yes, I agree. My reply was more in the context of the question.
Also, another possibility is about having a method that reports on the current progress of the thread. For example, something that a SwingWorker does.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Yes, I agree too. But the methods I'm talking about are real operations that the object has to do.
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

Marco Zanini wrote:Yes, I agree too. But the methods I'm talking about are real operations that the object has to do.

I think the whole point of implanting Runnable interface, as opposed to extending Thread class, is that the identity of the implementing instance remains separate. That is, the reason or purpose of existence of a class is not just to provide a certain functionality in a different thread, but more than that. For example, it may extend from JPanel, which implementing Runnable, and it's identity will be that it's a Panel. It will have all sorts of different method other threads and other classes may call, and it may choose to use the run() method, say to load data in its components asynchronously.

If the whole purpose of your class is just to provide the run() method, you may as well extend the Thread class, just like EventDispatchThread. You have to think on the lines of is-a relationship and decide what your class IS, and decide the methods it should have. Implementing Runnable shouldn't have any impact on this design, IMHO.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

Aditya Jha wrote:If the whole purpose of your class is just to provide the run() method, you may as well extend the Thread class, just like EventDispatchThread.


No. This is a gross misuse of OO. As a matter of fact, I consider it an absolute blunder by the language designers that they had Thread implement Runnable. A Thread is in no way a Runnable.

Anyway, you have no business using the Thread class anyway, unless you need to use the interrupt() or sleep() methods. At the risk of sounding like a broken record, use ExecutorService and Future instead.

[edit]

Just never use Thread. You can replace interrupt() with Future.cancel(), join() with Future.get() and sleep() with a timer of some sort.
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

Stephan van Hulst wrote:
Aditya Jha wrote:If the whole purpose of your class is just to provide the run() method, you may as well extend the Thread class, just like EventDispatchThread.


No. This is a gross misuse of OO. As a matter of fact, I consider it an absolute blunder by the language designers that they had Thread implement Runnable. A Thread is in no way a Runnable.

Anyway, you have no business using the Thread class anyway, unless you need to use the interrupt() or sleep() methods. At the risk of sounding like a broken record, use ExecutorService and Future instead.

[edit]

Just never use Thread. You can replace interrupt() with Future.cancel(), join() with Future.get() and sleep() with a timer of some sort.


I have heard this from many learned people and often wondered about the reason. Could you please explain a bit more on what's wrong with extending Thread, if the sole purpose of the class is to provide a functionality which is to be executed in a different thread (or, as a thread)? Does the objection come from design (your class is a 'functionality' and not a thread), or does it have more tech reasons?
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

No, it's purely conceptual. A Runnable is a task. Tasks are conceptually opposite to threads. Threads execute tasks. It makes no logical sense for a Thread to be Runnable, as evidenced by the fact that Thread's run() method does absolutely nothing at all, except for delegating to the Runnable you constructed it with.

Furthermore, extending the Thread class itself is an even bigger faux pas. I can not imagine that the average programmer needs a Thread to have more methods than the original designers chose to provide. The Thread class should probably have been declared final.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Excuse me but if I call create a Thread object by passing a Runnable argument to the Thread constructor, and then call the method start on the Thread created. That Thread will execute the code specified in the Runnable. But at this point if I call the methods of the Runnable class (the only way to call personalized methods) which Thread executes it?
Ranganathan Kaliyur Mannar
Bartender

Joined: Oct 16, 2003
Posts: 1076
    
  10

First of all, Runnable is an interface. I think you mean the class that implements Runnable and invoking the methods of that class. You will be invoking that from the 'current' thread that is usually the main thread.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Yes, the class that implements Runnable, sorry. If I make a Thread out of a Runnable, then start that thread, then call some methods of the class that implements Runnable, the code is executed by that class or by the Thread I started? Because if the code is executed by the class that implements Runnable there is no way to call Thread methods (the one from the class that implements Runnable) except the usual ones like wait, join, start, ecc.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

Code is not executed by any class. Code is executed by threads (note the lower case; I'm talking about actual threads, not the class).

If you create a Thread and call the start() method, Java will either ask the OS for a new thread, or simulate a new thread itself, and it will set that thread's instruction pointer to the start of the run() method.

Let's say we have a class Sensor that implements Runnable. Its run method will make temperature readings in a continuous loop, and broadcast the readings using radio.

Suppose the Sensor class also has extra methods, like a stop() method that interrupts the loop and other methods you can think of.

When you pass a Sensor to a Thread and start it, the Sensor will start collecting and sending data. Now, later on in the thread you used to call the start() method, you can call the stop() method when you have enough data.

Note that it's the main thread that's running the start() and stop() methods. The run() method is being run by the child thread that was spawned by Thread.start().

Indeed, the child thread may even terminate itself at some point by calling the stop() method. It all depends on your design.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
When you pass a Sensor to a Thread and start it, the Sensor will start collecting and sending data. Now, later on in the thread you used to call the start() method, you can call the stop() method when you have enough data.


Yes but I have to call the stop() method on the Runnable object because the Thread object doesn't have this method, even if the Runnable has it.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

Of course, that's the point. You want to stop the task, not the thread.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Yes but let me explain why I can't understand, step by step:

1) I create a class that implements the Runnable interface, this class has a special method, let's say stop()
2) I create an object of that class by calling the constructor, at this point in my program there are 2 objects running: the main class and the Runnable one.
3) I create a Thread giving it a reference to the Runnable object I created at step 2, and call it's start() method. At this point it seems to me that in my program there are 3 objects running: the main class, the Runnable one, and the Thread running its run() method, since I've called Thread.start().
4) At this point I call the Runnable.stop() method, from the main class, using the instantiated Runnable object reference.

I can't understand how it can affect the Thread object since there's no way to call the stop() method on it. It seems I misunderstood something.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

You don't run classes or instances. You can't have a main class and a Runnable class and a Thread class running.

A thread (lowercase) runs through code. Just imagine a thread as a pointer that points to the line number of the statement you're currently executing. At first when you start the program, there is only one such pointer, and it starts at the beginning of the main() method.

When you call Thread.start(), a second pointer appears, at the start of the run() method of the Runnable you passed to the Thread object. So now you have two pointers that run through code at the same time. If from the "main" pointer you call the stop() method on your task, you have two pointers running through code on the same object. The stop method can set a variable in the object that will cause the second thread to stop running the task.

Here is an example:
Here, a task will be created that continuously prints increasing values. The task is submitted to an executor (which internally uses threads, but you don't have to worry about that). The main thread then lets the task run for a second, and then calls the stop() method on the task. The stop method will cause the while loop to finish, so the task completes.

The main thread calls the future.get() method to make sure the main thread doesn't continue until the task is finished. It's use here is analogous to the use of the Thread.join() method.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Mmm so let's say when you call future.get() and task.stop() you're referring to the same Thread?
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

No, you're referring to a Task and a Future.

task.stop() will let the current thread (the main thread at that point in the program) set the boolean running to false. Another thread that was spawned by the ExecutorService will read this boolean, and decide to break out of the while loop. Task.stop() influences what the other thread does (very effectively) but it does not manipulate the thread directly.

Future.get() will cause the current thread (the main thread again) to block until the ExecutorService has determined that the child thread has finished running the Task.

Maybe I'm misunderstanding what you mean by "referring to the same Thread", but it's important to use the right terminology.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Ok I think I understand. But is wrong to add for example another method in Task that prints out some other things, when calling it the future Thread will not be affected.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

That's perfectly valid. Your Task could have a method that returns the current state of the task, some status information, or whatever. The thread executing these methods will be the main thread, while the child thread is busy performing the task at hand. Just remember to synchronize access properly.
Warren Dew
blacksmith
Ranch Hand

Joined: Mar 04, 2004
Posts: 1332
    
    2
Marco Zanini wrote:2) I create an object of that class by calling the constructor, at this point in my program there are 2 objects running: the main class and the Runnable one.

Perhaps this is where the misconception is. At this point, there is still only one thread running, the main thread. The Runnable is just an object that got created; it's not "running". If you constructed a String, it wouldn't be "running" either; it would also just be an object that got created.

It isn't until you call Thread.start() that there is more than one thread. Then that new thread calls Runnable.run(), so the run() method is running in the new thread. Meanwhile, the main thread is still around, doing other things.
Marco Zanini
Ranch Hand

Joined: Oct 31, 2011
Posts: 43
Thank you very much to everyone that replied. I think now I got a better knowledge about how Java threads work.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Stephan van Hulst wrote:
Aditya Jha wrote:If the whole purpose of your class is just to provide the run() method, you may as well extend the Thread class, just like EventDispatchThread.


No. This is a gross misuse of OO. As a matter of fact, I consider it an absolute blunder by the language designers that they had Thread implement Runnable. A Thread is in no way a Runnable.


++ INFINITY
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Methods for threads?