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

Pausing and restarting other threads at arbitrary times

Will Bramble
Greenhorn

Joined: Jan 21, 2006
Posts: 10
Hi,

This will sound like a rehash of the old 'why can't I use suspend/resume', and in a way it is, but after doing some net searching I'm wondering if there really is a way to pause and restart other threads from, say, a master controlling thread, at arbitrary times. This would be incredibly useful.

And the 'arbitrary times' requirement implies that the threads to be paused should not be using any state checking logic of their own to decide when to pause. eg. if (shouldIPausedNow) wait(); .

I noticed a snippet of text in the new concurrency utils doco for the Condition class which was interesting, and maybe implied that it could do what I was after:

"A Condition implementation can provide behavior and semantics that is different from that of the Object monitor methods, such as guaranteed ordering for notifications, or not requiring a lock to be held when performing notifications. If an implementation provides such specialized semantics then the implementation must document those semantics."

But it doesn't elaborate on that, and the rest of the documentation indicates that (as we're already accustomed to) an IllegalMonitorStateException would be thrown if a wait call is made by a thread other than the one holding the lock..?

I understand that it's a big ask to pause a thread when it could really be doing anything, in an unstable state, etc.. but it would be nice if this were supported, perhaps at the VM level.

Any ideas, or is this a lost cause?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
"not requiring a lock to be held when performing notifications" - they aren't necessarily talking about notify() or notifyAll() here. This is a more general sense of the word. With a Condition, you use await() and signal()/signalAll() rather than wait() and notify()/notifyAll(). The Condition methods don't require synchronization, but the traditional wait/notify methods still do.


"I'm not back." - Bill Harding, Twister
Will Bramble
Greenhorn

Joined: Jan 21, 2006
Posts: 10
Yep, understand that Condition uses different calls in await() and signal()/signalAll() rather than wait() and notify()/notifyAll().

So can I legitimately call await(), signal()/signallAll() for a lock from a different thread which does not hold the lock?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
I see - I read your question too quickly.

It's theoretically possible to have a Condition which allows you to do this, yes. Condition is an interface, and this behavior is allowed. The interface also allows implementations to throw IllegalStateException if the lock is not held (or for other reasons), and stipulates that it's the responsibility of the implementation (or subinterface) to document what behavior is to be expected. This means you have to look at the particular Lock which you got the Condition from. As far as I know, the only Lock implementations available in JDK 5 are

  • ReentrantLock
  • ReentrantReadWriteLock.WriteLock
  • ReentrantReadWriteLock.ReadLock
  • ConcurrentHashMap.Segment

  • The first two specifically document that their newCondition() method returns a Condition which throws IllegalStateException if wait/notify methods are called without holding the lock. The third doesn't even allow you to create a Condition, and the fourth is a non-public class which inherits newCondition() from ReentrantLock anyway.

    So, for existing JDK 5 classes, no. You can't call wait/notify methods without holding the lock. Unless you provide your own Lock/Condition implementations, or find some from a third party. Then, it's possible. AbstractQueuedSynchronizer may have some building blocks that would be useful in such an endeavor. Don't know much else about it, myself - guess you just have to read the specs carefully. Enjoy.
    Will Bramble
    Greenhorn

    Joined: Jan 21, 2006
    Posts: 10
    Hi Jim, thanks for your excellent responses.

    I guess I'll have to keep looking for now, but I have a feeling that what I'm after may not be possible because it's inherently unsafe at the JVM level ie. pausing of threads when they could be in an indeterminate state.

    It would be really handy to have though. Imagine you have a game interface, where there are many threads each dealing with different game elements on screen, and then the user may wish to momentarily pause everything (or at least the game threads) while they change settings, etc.

    If this can't be done in Java then it's a serious shortcoming.

    One possible, yet very long-winded way would be to create a nested VM and scripting language of sorts within Java so that even if you don't have control of pausing the JVM itself, you can pause the execution of your own scripting language. A very roundabout solution, but one that's been used before (see UnrealScript) to great effect..
    Jim Yingst
    Wanderer
    Sheriff

    Joined: Jan 30, 2000
    Posts: 18671
    Well, I suppose you could try using suspend() and resume() even though they're deprecated. It seems risky, but possible. The challenge then becomes trying to figure out what the "critical system resources" are, and make sure the threads you want to pause are never locking those resources. Dunno if that's possible, but it might be worth a try.

    However, I'd be more inclined to just implement a static checkForPause() utility method somewhere that checks to see if a boolean has been set to true, and if so, blocks until it's set to false. Once you get that working, just sprinkle that method liberally through all your thread code. Anywhere you're not holding a lock on some critical system resource. I'm thinking that in a game, most of these threads are probably in loops that repeat many times a second (e.g. once per screen refresh) - it should be sufficient to call checkForPause() just once at the beginning of the loop. I don't think this is as difficult as you seem to imply - the API is just set up to encourage you to think about where pauses may be appropriate. I think it's a good thing that they don't make this too easy (as they had with suspend/resume), because that makes it too easy to get in deadlock or other troubles. Maybe that means I'm just blindly following the company line here - but I think you should give it a shot. Unless you've already been down this road and found problems with this approach?
    [ January 22, 2006: Message edited by: Jim Yingst ]
    Will Bramble
    Greenhorn

    Joined: Jan 21, 2006
    Posts: 10
    Hmm I think I'll be steering clear of the suspend() and resume() calls, even if they do still work for now.. it's living dangerously. It's unfortunate, especially with those methods defined on ThreadGroup as well which may have been perfectly suited for this sort of purpose.

    The liberal sprinkling of 'flag watch' code is really what I'm trying to avoid, but I take your point about this encouraging the developer to think more about the control of their threads, and therefore the careful design of the code that utilise them. It does make sense from that end.

    As it is though I'm starting to think that it might be a little crazy trying to use concurrent Java threads for my particular project, where many threads would be active within an engine, each doing their own task.. or at least a portion of it within a discrete universal time unit, which is where the problem would come in: some threads would naturally sneak in more time than others within that time unit, leading to some inconsistent results. There's not enough control.. and yes I'm talking to myself now..

    Thanks for the insightful responses anyway.
    Tanu Kumar
    Greenhorn

    Joined: Dec 07, 2005
    Posts: 10
    I have query, I want to have a deoman thread running, and it shoudl run after every 20sec/min ( configurable) how do i achieve this?
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Pausing and restarting other threads at arbitrary times