aspose file tools*
The moose likes Beginning Java and the fly likes Using Objects in Static Recurring Processes Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Using Objects in Static Recurring Processes" Watch "Using Objects in Static Recurring Processes" New topic
Author

Using Objects in Static Recurring Processes

Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Hi folks; I have kind of a design/philosophical question (I think )

Lets say that I have a timer that I'd like to turn on and off at will from any portion of my program. The timer fires and activates an external peripheral via a socket connection. The two ways I have found to do this are to:

1) Make the timer static and use wait() and notify() statically.

and in an effort to try and make this OO

2) Create a new Timer object each time I want to activate the timer. And use wait() to terminate it. Instantiate it again when I need it.



Number 1 works well; but I am not sure that is best practice in an OO design. Number 2 scares me because it seems like I am leaving a bunch of threads in wait that never get woken up.

So, I am thinking that there is a 3rd option I am not considering. This is probably indicative a bigger gap in my knowledge regarding the way threads should be used. In the example above, I use a timer which can be made static. In the example of a runnable class this doesn't work because threads can't be static.

Anyway, hopefully I've made my self clear. Thanks for any help you guys can provide.


‎"The greatest of all weaknesses is the fear of appearing weak." - JB Bossuet
Hunter McMillen
Ranch Hand

Joined: Mar 13, 2009
Posts: 492

You could just keep one Timer instance for the whole duration of your program, so when you need an instance of Timer, you call a method in the Timer class to get the current instance of the Timer object, then you can activate it and do what you want with it. There was a big debate here in the last few days about the Singleton pattern which you may find interesting to read. The other design pattern the can accomplish this is the Factory pattern, it is described in the Singleton thread and very well on wikipedia.

Singleton thread: http://www.coderanch.com/t/542172/java/java/Singleton-pattern
Factory Pattern: http://en.wikipedia.org/wiki/Factory_method_pattern
Singleton Pattern: http://en.wikipedia.org/wiki/Singleton_pattern


hope this helps.
Hunter


"If the facts don't fit the theory, get new facts" --Albert Einstein
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Hunter McMillen wrote:You could just keep one Timer instance for the whole duration of your program, so when you need an instance of Timer, you call a method in the Timer class to get the current instance of the Timer object, then you can activate it and do what you want with it. There was a big debate here in the last few days about the Singleton pattern which you may find interesting to read. The other design pattern the can accomplish this is the Factory pattern, it is described in the Singleton thread and very well on wikipedia.

Singleton thread: http://www.coderanch.com/t/542172/java/java/Singleton-pattern
Factory Pattern: http://en.wikipedia.org/wiki/Factory_method_pattern
Singleton Pattern: http://en.wikipedia.org/wiki/Singleton_pattern


hope this helps.
Hunter


Super super helpful Hunter. I've been dancing around this for a long time and these links explain a lot. I'm off to experiment with the singleton. Thank you!
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Hi Hunter and everyone else.

So now I have a singleton named scoreboard with a timer object (timer1) inside of it. I can get it to work ok, but in order to stop the timer I have to use a setter (setMode) inside of the singleton that takes takes a boolean argument and flips a boolean value (scoreBoardState) that is used in an if statement in the timer object to stop the timer. However I can use



to kick it off again.

My question is, why can't I use



instead of having to use a wonky setter. I'm thinking I can but not sure what I am missing. This compiles fine but it just won't stop the timer.


My code may prove helpful; I've omitted some methods that aren't relevant for clarity.

Here is the singleton.



Thanks



Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

The notify() and wait() methods don't know anything about what the Timer is doing, they are just synchronization primitives. You shouldn't expect them to change the behaviour of the Timer in any way.

You mentioned a boolean flag? That's what I would use. Set it to true initially, set it to false if you want the Timer to appear to be stopped, then set it back to true if you want the Timer to appear to be running. Then the TimerTask it's running should only do something if the flag is true.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Paul Clapham wrote:The notify() and wait() methods don't know anything about what the Timer is doing, they are just synchronization primitives. You shouldn't expect them to change the behaviour of the Timer in any way.

You mentioned a boolean flag? That's what I would use. Set it to true initially, set it to false if you want the Timer to appear to be stopped, then set it back to true if you want the Timer to appear to be running. Then the TimerTask it's running should only do something if the flag is true.


Thanks for the reply Paul. I am not sure I follow you entirely on the "synchronization primitives". wait(); and notify(); do not stop and start the timer? I can see my way to set the flag up the way you suggest, I just want to make sure I understand how the wait() and notify() methods work.

Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

Well, you could certainly read a threading tutorial if you want to know what those methods do. I would definitely recommend that. For the purposes of this thread, though, I will just restrict myself to saying that they don't do what you imagine they do. In particular they don't cause the object on which they are called to do anything at all, they just use that object as a synchronization monitor.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Thank you Paul.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

I read several tutorials on wait/notify/notifyAll last night. Many of them talk about multiple threads operating on the same object and how that object is locked until it is ready for the next thread to operate on it. Or two threads communicating and one feeds the other. The feeder is wait()s until the consumer is done (notify()ed). I read item 69 in "Effective Java" (Bloch) and he makes several interesting points about wait() and notify(). The most important in my opinion is; "Don't use them for new code". Rather he suggests using Executors to accomplish the same things.The other is he uses the terms "sleep" and "wake"in reference to wait() and notify() which sounds to me like "stop" and "start"; given that a timer is a thread (I think) it sounds to me like using wait and notify to stop/start a thread works but isn't best practice. So it seems like I need to ditch the whole idea of using these. That leads me to two questions:

First, in an effort to understand wait() and notify() :

1) Paul (or whoever else might feel like chiming in), I also wanted to run this by you. One of the reasons I was so confused about your comment ("They don't work they way you imagine.") in a previous operation wait() and notify() worked exactly as I imagined. Here is the example; I am removing the meat of a lot of this for clarity.


Here is the first Class with the thread. This class constantly runs and checks a given condition (motion on a scale). If there is not motion it just repeats. If there is motion, I activate an RFID reader and to get a tag ID. It doesn't matter whether I get a tag id or not because in either case I tell the timer (or the thread containing the timer) to wait.( I realize that the the timer shouldn't be static and I should use a singleton like Hunter suggests but I wrote this prior to asking my question and understanding singletons)
In this case the Timer does stop; or sleeps, or does something completely different and the end result is that the timer stops. Thats where I'm cloudy. On to the second class where I notify() it.





This takes over when the scale returns to zero. I go off and do a bunch of processing stuff from class one (goWeighment) but none of those things affect the wait()ing scaleMonitor thread from class1. Once the scale returns to zero I notify() the static timer (scaleMonitor) in class 1. It "wakes" up and begins to look for motion again. Here is the code:



So in this case, wait() stops the thread. notify() starts the thread. Of course thats why I was so confused about the new object I was writing that you and I were discussing Paul. I could get wait() to stop the thread but when I tried to notify() like I did in in the above example, no dice.
Is it because the Timer in this example is static and the timer in my new class isn't? Since I am dealing with a Static timer in the example above does that mean I am making the thread the owner of its own monitor by invoking wait () and therfore locking itself? internally and then notifying it it externally? Versus trying to do the same with a non static timer where even If use the singleton pattern, the owenrship monitor doesn't behave as it does with a static object?
Hopefully you can see my confusion here and I am not being to dense. There is something I am missing here under the hood.




2) Since I have it all wrong about notify() and wait(), what is best practice for activities that I want to be run on a schedule but have the control to pause and restart them? Using your advice Paul I was able to use the Boolean flag inside of the singleton to enable or disable operations to make it appear as if the timer had stopped. It kept running but it wasn't actually executing anything until the flag was true.
I read about Quartz last night and that seems like it has the standby() and start() methods that could be used for this kind of function but might also be over kill. In "Effective Java" Bloch recommends using the newer Executor APIs to accomplish these. kinds of things.
Maybe this is one of those situations where its up to the dev to make the best choice.




Anyhow, thank you for discussing this with me Paul and Hunter. I am really getting a lot of of the process and appreciate your patience.


Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

Cory Hartford wrote:Is it because the Timer in this example is static and the timer in my new class isn't?


You synchronize on objects, not on variables. So it makes no difference whether you have an instance variable referring to your Timer object, or a static variable, or both for that matter. In fact it doesn't even make sense to describe an object as "static". No matter what you do with an object, it makes no difference that there happens to be a static variable which contains a reference to it. So that's nothing to do with anything.

I have to admit that I didn't read all of that post. Way too much information, and when you have fundamental misconceptions like the above, it's probably best to just deal with them first.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

Cory Hartford wrote:I read several tutorials on wait/notify/notifyAll last night. Many of them talk about multiple threads operating on the same object and how that object is locked...


Did they really use that terminology? Because you don't actually "lock" an object, even though you see that phrase a lot. Instead, you own the object's monitor. Only one thread at a time can own an object's monitor, and it's synchronizing on the object that allows it to do that. And when you synchronize on an object's monitor, you don't prevent any other code from doing anything else with that object. You don't prevent the object itself from doing anything, either. Unless that code happens to try to synchronize on the object whose monitor you already own, in which case it will wait until you relinquish that monitor. (But now I'm repeating what was already in the tutorial you read.) It's perfectly possible for other code not to bother synchronizing on an object, in which case your code's synchronization has no effect.

So if you found that synchronizing on a Timer and calling its wait() method caused it to stop scheduling tasks, that's most likely because the Timer tries to synchronize on itself before it does that. But the API documentation for Timer doesn't say that (does it?) and so you shouldn't rely on that behaviour, if indeed it does work that way.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

I also don't get why you declared your Timer static. You just need one Timer, right? So just create one. You don't need to mess about with static variables or even singleton classes for that. Just create one. The easiest way to do that is to make it an attribute of your ScaleMonitor class, that way you get one Timer per ScaleMonitor.

And notice how you have just one ScaleMonitor? You didn't need any singleton logic for that, did you? You just created one when you needed it. Just create one.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

I like your 2nd reply much butter than the first.
Thanks. I appreciate the help and will look into the proper solution; whether thats the boolean flag, trying out the Concurrency stuff, or messing with Quartz.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Paul Clapham wrote:I also don't get why you declared your Timer static. You just need one Timer, right? So just create one. You don't need to mess about with static variables or even singleton classes for that. Just create one. The easiest way to do that is to make it an attribute of your ScaleMonitor class, that way you get one Timer per ScaleMonitor.

And notice how you have just one ScaleMonitor? You didn't need any singleton logic for that, did you? You just created one when you needed it. Just create one.



The timer is static (right or wrong) because I could call notify() on it outside of the class to start it up again. The reason I used the singleton is because Hunter suggested that this methodology made it possible to control the same timer (pause, start) at any point in the program. I didn't want to create a gaggle of timers or scale monitor objects for that matter; It made more sense to me to have one and turn it off and on as I need it rather than spawning a new object each time. Maybe I'm thinking about it totally wrong but that was the idea.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

Well, you're making a lot of bad decisions because you don't seem to know basic things like how to keep references to objects you need to work with. I think you should start over and design how these things are going to work together.

Design like this, for example: You have a thing called "ScaleMonitor". What is its responsibility? In other words, what is it supposed to do? Does it need a Timer to do that? If so, it should have a Timer declared in it. And also it should be in charge of what the Timer does, it shouldn't pass the Timer around and let other classes mess around with it.

My preferred way to start and stop a timer is like this: to start a timer, create a new Timer object and start it up by calling one of the "schedule" methods. And to stop the timer, call the Timer's "cancel" method. Trying to pause a Timer won't work because it isn't designed to be paused.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Paul Clapham wrote:. Trying to pause a Timer won't work because it isn't designed to be paused.


This concept would have saved me a lot of time. I came from a language that had timers that once declared could be stopped, started, reset etc. So I was tainted in my thinking about timers in Java; it seemed silly to me to have a timer that you couldn't control. When I found notify() and wait) I thought, "aha, stop and start".
I think I know how to keep references to objects. I created several references at the top of class1 (goWeighment is a reference to WeighmentProcessBegin right?) . Is that what you are referring to? I threw static on the timer to experiment and (apparently) mis-use wait() and notify(); and it worked but in a hackey, "it shouldn't work" kinda way. Using the reference to notify() wouldn't work.
After going through all of this discussion though, the whole deal was a fool's errand. And you're right; my design efforts need improvement. I think my design ideas will get better as I master the language APIs and what they can do. I'm still only a year and half into this so I am bound to make mistakes. I'm glad there is a beginning Java forum where I can come to get straightened out when I am really stuck. :thumbup:
These two classes are a mess because I spent several days trying to essentially start and stop a timer. Based on our discussions (which, by the way, I really appreciate) I'll head back to the drawing board on Monday and rework this stuff taking into account what I have learned.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Also, I hope this helps other people when they are starting out with timers; gotta love forums. Stone tablets of the internet.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Paul Clapham wrote:I also don't get why you declared your Timer static. You just need one Timer, right? So just create one. You don't need to mess about with static variables or even singleton classes for that. Just create one. The easiest way to do that is to make it an attribute of your ScaleMonitor class, that way you get one Timer per ScaleMonitor.

And notice how you have just one ScaleMonitor? You didn't need any singleton logic for that, did you? You just created one when you needed it. Just create one.



I guess I'm a glutton for punishment, because I'm back with more questions.

I went ahead and did as you suggested Paul. I have one object, with a timer declared in it, doing the one thing it's supposed to do and thats it.

I instantiate the object in question and start the timer via the object reference.

I'm on a roll and everything is great.

Unfortunately, like you mentioned earlier, I don't know how to keep a reference to the same instance of the object so that I can call .cancel() on the timer contained in the correct object instance. I can do it within the class where I made the deceleration using the same object reference, which is fine, but how I do I pass that object reference around/make it available to other classes so that when I want to call .cancel() on the timer, I can do so in the correct instance. Or heck, even if I wanted to make a stopTimer() method in the object how would be able to identify the correct instance?

The thought that I have is to capture the object reference at the time of instantiation and write it to a storage variable in a class so I can grab it later. That puts me back in Singletonville though; the only way that'd work is if I had only one instance active at a time and at that point I might as well use a singleton.

Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

Cory Hartford wrote:Unfortunately, like you mentioned earlier, I don't know how to keep a reference to the same instance of the object so that I can call .cancel() on the timer contained in the correct object instance. I can do it within the class where I made the deceleration using the same object reference, which is fine, but how I do I pass that object reference around/make it available to other classes so that when I want to call .cancel() on the timer, I can do so in the correct instance.


You don't. Don't pass the Timer around so that other code can modify it. Your class (ScaleMonitor?) which contains the reference to the Timer should be the only code which works with the Timer. If other code needs to work with the timer, then ScaleMonitor should provide public methods to do that, rather than exposing the Timer. Example fragment:


By the way this is called "encapsulation". One of the foundational principles of object-oriented design.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

So:

When I am ready to start the timer from the client code:

Scalemonitor cory = new ScaleMonitor();
cory.startTimer();


From another class I want to go ahead and stop it.
ScaleMontior Paul = new ScaleMonitor();
Paul.stopTimer();


The Paul Instance is going to stop the Timer in the Cory Instance?





Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

I'm pretty sure it doesn't; but that goes back to my first question. How can I retrieve the same instance that started it so that I can use it again to .cancel() it from another location. I'd have to store that instance reference somewhere and retrieve it?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

You are right, there are two separate instances in that code. But "retrieving" an instance is the wrong way to go about things. Just don't lose track of the reference in the first place. And if more than one class needs a copy of the reference, just pass it one. The best place to do that would be in your controller, when you are setting things up. Example of a class which needs a reference to the ScaleMonitor:


Example of controller code:
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Aha! Very good sir; makes total sense. My design will have to be improved in order to take advantage of this which is for the better anyhow.

Thanks!
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18662
    
    8

Just remember: Object-oriented design is about objects. If you find yourself thinking about variables, you are going down the wrong road. It's all about objects and what they can do.
Cory Hartford
Ranch Hand

Joined: May 16, 2011
Posts: 82

Aye aye cpt! Will do.
Thanks again.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Using Objects in Static Recurring Processes