 |
AppletTalk.com Java discussions newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Bryan R. Meyer Guest
|
Posted: Tue Apr 27, 2004 2:39 am Post subject: Pausing Threads From Events |
|
|
Hello Everyone,
Hopefully, someone has some pointers for my problem. Suppose I have
an applet which starts a new thread A. The applet implements
MouseListener and when the user puts the mouse over the applet, a
MouseEvent occurs. When a user generates this MouseEntered event,
thread A is to be paused. Unfortunately, the currently executing
thread is AWT-EventQueue. How can I pass that event to thread A so
that I can pause the thread?
Thanks for any suggestions. I haven't been able to find much on this
subject.
Bryan
|
|
| Back to top |
|
 |
Knute Johnson Guest
|
Posted: Tue Apr 27, 2004 3:08 am Post subject: Re: Pausing Threads From Events |
|
|
Bryan R. Meyer wrote:
| Quote: | Hello Everyone,
Hopefully, someone has some pointers for my problem. Suppose I have
an applet which starts a new thread A. The applet implements
MouseListener and when the user puts the mouse over the applet, a
MouseEvent occurs. When a user generates this MouseEntered event,
thread A is to be paused. Unfortunately, the currently executing
thread is AWT-EventQueue. How can I pass that event to thread A so
that I can pause the thread?
Thanks for any suggestions. I haven't been able to find much on this
subject.
Bryan
|
Create a volatile boolean for a flag and set the flag in your listener
code. In the run() of your thread, test the flag, if it is true, pause.
class ??? {
volatile boolean flag = false;
// Listener code
flag = true;
// run()
if (flag)
// pause
}
--
Knute Johnson
email s/nospam/knute/
Molon labe...
|
|
| Back to top |
|
 |
Roedy Green Guest
|
Posted: Tue Apr 27, 2004 3:31 am Post subject: Re: Pausing Threads From Events |
|
|
On 26 Apr 2004 19:39:46 -0700, [email]bryan.r.meyer (AT) verizon (DOT) net[/email] (Bryan R.
Meyer) wrote or quoted :
| Quote: | How can I pass that event to thread A so
that I can pause the thread?
|
You never pause the AWT thread that handles an event. If it has
something lengthy to do, it should spin off a new thread, or signal
some other already running thread to do the work.
While you are in your event handler nothing else in the GUI can
happen, no mouse clicks, no http://mindprod.com/jgloss/thread.html
--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
|
|
| Back to top |
|
 |
Rob Shepherd Guest
|
Posted: Tue Apr 27, 2004 8:36 am Post subject: Re: Pausing Threads From Events |
|
|
Bryan R. Meyer wrote:
| Quote: | Hello Everyone,
Hopefully, someone has some pointers for my problem. Suppose I have
an applet which starts a new thread A. The applet implements
MouseListener and when the user puts the mouse over the applet, a
MouseEvent occurs. When a user generates this MouseEntered event,
thread A is to be paused. Unfortunately, the currently executing
thread is AWT-EventQueue. How can I pass that event to thread A so
that I can pause the thread?
Thanks for any suggestions. I haven't been able to find much on this
subject.
Bryan
|
I paused a thread in this manner:
two ojects A and B. A is a gui and pauses/resumes Thread B.
thus in class A
[two buttons start and stop]
....
b = new B();
b.start();
stop.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
synchronized(b)
{
b.paused = true;
}
stop.setEnabled(false);
start.setEnabled(true);
}
} );
start.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
synchronized (a)
{
b.paused = false;
b.notify();
}
start.setEnabled(false);
stop.setEnabled(true);
}
} );
....
[in the class for object b (above)]
....
public boolean paused = false;
public void run()
{
while(true)
{
synchronized(this)
{
while(paused)
{
try
{
wait(); // this object is now paused....
}
catch (Exception e)
{
}
}
}
////Here i do some stuff when not paused
}
}
....
regards
|
|
| Back to top |
|
 |
Bryan R. Meyer Guest
|
Posted: Tue Apr 27, 2004 9:10 pm Post subject: Re: Pausing Threads From Events |
|
|
Roedy Green <see (AT) mindprod (DOT) com.invalid> wrote
| Quote: | You never pause the AWT thread that handles an event. If it has
something lengthy to do, it should spin off a new thread, or signal
some other already running thread to do the work.
|
I suppose I wasn't as clear as I should have been. I DO NOT wish to
pause the AWT thread. I wish to pause thread A. However, if the user
generates a MouseEvent, and in the event handler I call a method -
pauseThread() - to pause the thread by doing a wait(), the result is a
IllegalMonitorStateException: current thread not owner. In this case,
the AWT thread is still handling the event so thread A can't wait. My
question was how can I pause thread A as a result of the MouseEvent
despite the fact that the AWT event thread is the currently executing
thread?
Rob's code seems to make sense, but in his object B, he seems to have
a busy wait when he checks to see if the thread is paused. Or is this
not a busy wait since the thread (and loop) are blocked when wait() is
called in the loop? Can this be avoided?
while(paused) {
try {
wait(); // this object is now paused....
}
catch (Exception e) {
}
}
Thanks,
Bryan
|
|
| Back to top |
|
 |
Rob Shepherd Guest
|
Posted: Wed Apr 28, 2004 11:45 am Post subject: Re: Pausing Threads From Events |
|
|
Bryan R. Meyer wrote:
| Quote: | Roedy Green <see (AT) mindprod (DOT) com.invalid> wrote
You never pause the AWT thread that handles an event. If it has
something lengthy to do, it should spin off a new thread, or signal
some other already running thread to do the work.
I suppose I wasn't as clear as I should have been. I DO NOT wish to
pause the AWT thread. I wish to pause thread A. However, if the user
generates a MouseEvent, and in the event handler I call a method -
pauseThread() - to pause the thread by doing a wait(), the result is a
IllegalMonitorStateException: current thread not owner. In this case,
the AWT thread is still handling the event so thread A can't wait. My
question was how can I pause thread A as a result of the MouseEvent
despite the fact that the AWT event thread is the currently executing
thread?
Rob's code seems to make sense, but in his object B, he seems to have
a busy wait when he checks to see if the thread is paused. Or is this
not a busy wait since the thread (and loop) are blocked when wait() is
called in the loop? Can this be avoided?
while(paused) {
try {
wait(); // this object is now paused....
}
catch (Exception e) {
}
}
Thanks,
Bryan
|
This part if the thread just checks to see if paused is true.
If it is then the thread will pause inside the wait() function.
Ie. the wait() method does not return immediatly. the wait() method returns when the
object has been notified and the lock(b) is available for other classes again.
I find this code works for loops which take a medium amount of time to complete.
Too long and then user will have to wait until the end of the nonpaused section to see the
pausing effect.
Imaging if there were a blocking section in the nonpaused bit. if it were paused whilst in
this blocked area of code the Thread would appear paused but then when the blocked bit
comes free, you would see the remaining code execute THEN it would pause!!.
having while(paused) instead of if(paused) is better because wait() can be interrupted.
If it does get interrupted then it will just wait again.
good luck
rob
|
|
| Back to top |
|
 |
NOBODY Guest
|
Posted: Wed Apr 28, 2004 12:25 pm Post subject: Re: Pausing Threads From Events |
|
|
Yes, I got answers for you.
I'm sorry to tell you the following but you should mostly ignore the
answers you got. These techniques are not professionnal. Period.
1st, you sure will have a boolean to change/check somewhere, but
the volatile keyword (that supposably protects threads from processor
caching) is not implemented in many jvm. You may easily confirm that hot
topic with a simle search on the web.
2nd, the only sure way to do "messaging" between threads required the use
of a "synchronized" zone, that forces the thread fo resync with memory.
This is critical in multiprocessors platforms.
3rd, your thread to be paused need to cooperate, i.e. it must be ready to
be notified or capable to handle interruptions (only one of the 2
technique is enough, and I suggest you go with notifiations, it is less
work, although you might want to combine both)
-----------
package tests;
import java.io.InterruptedIOException;
public abstract class PausableLoopThread extends Thread {
long delay;
//critical zone 1:-----
final Object lock = new Object();
boolean paused = false;
boolean running = false;
//---------------------
boolean requestedInterrupt = false;
public PausableLoopThread(String name, long delay) {
this(null, name, delay);
}
public PausableLoopThread(ThreadGroup group, String name, long
delay) {
super(group, name);
if(delay<=0)
throw new IllegalArgumentException("delay <= 0");
this.delay = delay;
}
public final void interrupt() {
requestedInterrupt = true;
super.interrupt();
}
public final void run() {
synchronized(lock) {
running = true;
}
while(true) {
boolean _p;
synchronized(lock) {
if(!running)
break;
_p = paused;
} //unlock zone to process loopImpl, otherwise
changePause() would block while loopImpl() running (may be long)
if(!_p) {
try {
loopImpl();
} catch(InterruptedException e) {
if(!requestedInterrupt)
System.err.println("Thread was
interrupted by another unexpected way!");
break;
} catch(InterruptedIOException e) {
if(!requestedInterrupt)
System.err.println("Thread was
interrupted by another unexpected way!");
break;
} catch(Exception e) {
if(requestedInterrupt) { //detect stupid 3rd
party that do not rethrow Interrupts
System.err.println("Thread was
interrupted but didn't throw InterruptedException: "+e);
//e.printStackTrace();
break;
} else {
e.printStackTrace();
}
}
}
synchronized(lock) {
try {
lock.wait(paused ? 0 : delay); //gets out by
timeout of by notify
} catch(InterruptedException e) {
if(!requestedInterrupt)
System.err.println("Thread was
interrupted by another unexpected way!");
break;
}
}
}
}
protected abstract void loopImpl() throws InterruptedException,
InterruptedIOException;
public final void requestPause() {
changePause(true);
}
public final void requestResume() {
changePause(false);
}
private void changePause(boolean pause) {
synchronized(lock) {
boolean b = this.paused;
this.paused = pause;
//if(!pause && b!=pause) //notify only if resumed, why
waking up a waiting thread!
lock.notify();//kick out of wait
}
}
public final void requestStop() {
synchronized(lock) {
this.running = false;
lock.notify();//kick out of wait, if any
}
}
//========
public static void main(String[] args) throws Exception{
PausableLoopThread p = new PausableLoopThread("pt", 300) {
final long t0 = System.currentTimeMillis();
protected void loopImpl() throws InterruptedException,
InterruptedIOException {
System.out.println("loop it! "+
(System.currentTimeMillis()-t0));
}
};
p.start();
Thread.sleep(4000);
p.requestPause();
Thread.sleep(4000);
p.requestResume();
Thread.sleep(4000);
p.requestStop();
//p.interrupt();
Thread.sleep(4000);
}
}
[email]bryan.r.meyer (AT) verizon (DOT) net[/email] (Bryan R. Meyer) wrote in
news:7a882edc.0404261839.233cfd3b (AT) posting (DOT) google.com:
| Quote: | Hello Everyone,
Hopefully, someone has some pointers for my problem. Suppose I have
an applet which starts a new thread A. The applet implements
MouseListener and when the user puts the mouse over the applet, a
MouseEvent occurs. When a user generates this MouseEntered event,
thread A is to be paused. Unfortunately, the currently executing
thread is AWT-EventQueue. How can I pass that event to thread A so
that I can pause the thread?
Thanks for any suggestions. I haven't been able to find much on this
subject.
Bryan
|
|
|
| Back to top |
|
 |
Rob Shepherd Guest
|
Posted: Wed Apr 28, 2004 2:09 pm Post subject: Re: Pausing Threads From Events |
|
|
NOBODY wrote:
| Quote: | Yes, I got answers for you.
I'm sorry to tell you the following but you should mostly ignore the
answers you got. These techniques are not professionnal. Period.
|
So only Java "Professionals" are allowed to post messages with fully working
endorsed guaranteed to work *this-what-you-MUST-do* code examples eh?
I was under the impression that these newsgroups provide simple help for people who need
(amongst other things) a gentle push in the right direction.
The original poster, Bryan R Meyer, clearly has little experience with Threads and the
Thread model otherwise he would have included a code excerpt from his problem.
His statement "Hopefully, someone has some pointers for my problem" made me think...
1. I have done this before.
2. I have a simple solution working.
(which works all day every day as part of reliable system [on a multiprocessor machine])
3. It would be easy to copy-paste into a reply
4. Maybe he (and others) might benefit/learn more/take it further.
If only professional Java programmers were allowed to respond then i would imagine the
useful traffic would be rather small compared to requests-for-help from students,
hobbyists, academics, scientists etc.
If only code which is 100% guaranteed to satisfy the needs of the request was allowed then
I think not many people would be bothered to reply.
Frankly I find your attitude rude, pompous and totally against the spirit of these newsgroups.
Granted your code is well written, is the perfect solution and would be the kind of code
one would expect as an example in a latter chapter of a book on Threading.
Nevertheless don't you agree that books require early chapters, with simple examples, to
ease the learner into the new concepts?
I imagine your post is appreciated by Bryan
but why not try an opening paragraph such as.....
---
Hi, I have a fairly comprehensive solution. My example below makes use of synchronization
and is safe for use on multi processor machines.
Hope this helps
NOBODY
---
Sorry for the rant. You try and help people and "lord-god-of-Threading-upon-high" has to
go and beat you down....
regards
Rob
-----------------------------------------------------------------------------
I'm sorry to tell you the following but you should mostly ignore [this]
These techniques are not professional. Period.
- NOBODY 2004
-----------------------------------------------------------------------------
|
|
| Back to top |
|
 |
Ade Guest
|
Posted: Wed Apr 28, 2004 2:30 pm Post subject: Re: Pausing Threads From Events |
|
|
Is it really necessary to criticize other people's solutions? I've
looked at this instance and seen code that is a lot less bloated than
yours and satisfies certainly conditions 2 and 3 that you state.
I thought the beauty of Java was that there are so many different ways
to do things - and no single way is better than all others, it's simply
different. The days of requiring perfect code that conforms to such
conditions are gone, and thank god that is so because at least now the
focus can increasingly be ideas and imagination rather than the details
of implementation.
Have a nice day
A
NOBODY wrote:
| Quote: | Yes, I got answers for you.
I'm sorry to tell you the following but you should mostly ignore the
answers you got. These techniques are not professionnal. Period.
1st, you sure will have a boolean to change/check somewhere, but
the volatile keyword (that supposably protects threads from processor
caching) is not implemented in many jvm. You may easily confirm that hot
topic with a simle search on the web.
2nd, the only sure way to do "messaging" between threads required the use
of a "synchronized" zone, that forces the thread fo resync with memory.
This is critical in multiprocessors platforms.
3rd, your thread to be paused need to cooperate, i.e. it must be ready to
be notified or capable to handle interruptions (only one of the 2
technique is enough, and I suggest you go with notifiations, it is less
work, although you might want to combine both)
-----------
package tests;
import java.io.InterruptedIOException;
public abstract class PausableLoopThread extends Thread {
long delay;
//critical zone 1:-----
final Object lock = new Object();
boolean paused = false;
boolean running = false;
//---------------------
boolean requestedInterrupt = false;
public PausableLoopThread(String name, long delay) {
this(null, name, delay);
}
public PausableLoopThread(ThreadGroup group, String name, long
delay) {
super(group, name);
if(delay<=0)
throw new IllegalArgumentException("delay <= 0");
this.delay = delay;
}
public final void interrupt() {
requestedInterrupt = true;
super.interrupt();
}
public final void run() {
synchronized(lock) {
running = true;
}
while(true) {
boolean _p;
synchronized(lock) {
if(!running)
break;
_p = paused;
} //unlock zone to process loopImpl, otherwise
changePause() would block while loopImpl() running (may be long)
if(!_p) {
try {
loopImpl();
} catch(InterruptedException e) {
if(!requestedInterrupt)
System.err.println("Thread was
interrupted by another unexpected way!");
break;
} catch(InterruptedIOException e) {
if(!requestedInterrupt)
System.err.println("Thread was
interrupted by another unexpected way!");
break;
} catch(Exception e) {
if(requestedInterrupt) { //detect stupid 3rd
party that do not rethrow Interrupts
System.err.println("Thread was
interrupted but didn't throw InterruptedException: "+e);
//e.printStackTrace();
break;
} else {
e.printStackTrace();
}
}
}
synchronized(lock) {
try {
lock.wait(paused ? 0 : delay); //gets out by
timeout of by notify
} catch(InterruptedException e) {
if(!requestedInterrupt)
System.err.println("Thread was
interrupted by another unexpected way!");
break;
}
}
}
}
protected abstract void loopImpl() throws InterruptedException,
InterruptedIOException;
public final void requestPause() {
changePause(true);
}
public final void requestResume() {
changePause(false);
}
private void changePause(boolean pause) {
synchronized(lock) {
boolean b = this.paused;
this.paused = pause;
//if(!pause && b!=pause) //notify only if resumed, why
waking up a waiting thread!
lock.notify();//kick out of wait
}
}
public final void requestStop() {
synchronized(lock) {
this.running = false;
lock.notify();//kick out of wait, if any
}
}
//========
public static void main(String[] args) throws Exception{
PausableLoopThread p = new PausableLoopThread("pt", 300) {
final long t0 = System.currentTimeMillis();
protected void loopImpl() throws InterruptedException,
InterruptedIOException {
System.out.println("loop it! "+
(System.currentTimeMillis()-t0));
}
};
p.start();
Thread.sleep(4000);
p.requestPause();
Thread.sleep(4000);
p.requestResume();
Thread.sleep(4000);
p.requestStop();
//p.interrupt();
Thread.sleep(4000);
}
}
[email]bryan.r.meyer (AT) verizon (DOT) net[/email] (Bryan R. Meyer) wrote in
news:7a882edc.0404261839.233cfd3b (AT) posting (DOT) google.com:
Hello Everyone,
Hopefully, someone has some pointers for my problem. Suppose I have
an applet which starts a new thread A. The applet implements
MouseListener and when the user puts the mouse over the applet, a
MouseEvent occurs. When a user generates this MouseEntered event,
thread A is to be paused. Unfortunately, the currently executing
thread is AWT-EventQueue. How can I pass that event to thread A so
that I can pause the thread?
Thanks for any suggestions. I haven't been able to find much on this
subject.
Bryan
|
|
|
| Back to top |
|
 |
Bryan R. Meyer Guest
|
Posted: Wed Apr 28, 2004 9:19 pm Post subject: Re: Pausing Threads From Events |
|
|
Rob Shepherd <robshep (AT) invalid (DOT) invalid> wrote
| Quote: | This part if the thread just checks to see if paused is true.
If it is then the thread will pause inside the wait() function.
|
Makes sense. The thread is essentially blocked and, therefore,
paused.
I appreciate the help. I don't quite understand the response given by
NOBODY. This is not for a professional project; it is merely for a
small personal project. I can't understand why such a function for
pausing threads is not already in the language. (Of course, I noted
the deprecation of suspend().)
Thanks again,
Bryan
|
|
| Back to top |
|
 |
Carl Howells Guest
|
Posted: Wed Apr 28, 2004 9:31 pm Post subject: Re: Pausing Threads From Events |
|
|
Bryan R. Meyer wrote:
| Quote: | I appreciate the help. I don't quite understand the response given by
NOBODY. This is not for a professional project; it is merely for a
small personal project. I can't understand why such a function for
pausing threads is not already in the language. (Of course, I noted
the deprecation of suspend().)
|
I can explain this one... But I may not need to. You say that you
noted that suspend() is deprecated. But did you read the rather large
document Sun put together explaining why many of the methods in Thread
are deprecated? It explains rather well.
As a simple recap, suspend() is dangerous. If you can arbitrarily
suspend another thread at any point in its execution, you can create
deadlocks. Requiring that the thread implement code to pause itself
safely (releasing all necessary locks, and making sure all data
structures it was using are in internally consistent states) increases
the safety of the threading system significantly.
|
|
| Back to top |
|
 |
Roedy Green Guest
|
Posted: Thu Apr 29, 2004 12:22 am Post subject: Re: Pausing Threads From Events |
|
|
On 28 Apr 2004 14:19:23 -0700, [email]bryan.r.meyer (AT) verizon (DOT) net[/email] (Bryan R.
Meyer) wrote or quoted :
| Quote: | I can't understand why such a function for
pausing threads is not already in the language.
|
There was, then they discovered it did not always work. So they
deprecated it all.
You can try something like StoppableThread.
See http://mindprod.com/products.html#BUS
part of the business package.
--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
|
|
| Back to top |
|
 |
Andrew Thompson Guest
|
Posted: Thu Apr 29, 2004 8:38 am Post subject: Re: Pausing Threads From Events |
|
|
On Wed, 28 Apr 2004 15:30:05 +0100, Ade wrote:
| Quote: | Is it really necessary to criticize other people's solutions?
|
Is it really necessary to repost 197
lines of the former post to ask that?
Please have a look over the entry after 'top-post'
<http://www.physci.org/codes/javafaq.jsp#netiquette>
While we are on the subject, and
in answer to your question.
"Yes"
This is a technical group (checks)
OK - I realise now it is going to
both c.l.j.programmer _and_ c.l.j.help
That complicates things..
Such 'rough and tumble' comments would usually
go by on c.l.j.p without raising a single
eyebrow, but converstaions on c.l.j.h are
usually conducted in a much more sensitive
manner.
Ultimately though, most people come to
the groups to get the best possible solution,
rather than to have a nice, polite chat.
In defence of the specific statement
"I'm sorry to tell you the following but
you should mostly ignore the answers you got.
These techniques are not professionnal. Period."
There are times you need to make a definitive
statement, at the top of the post, that other
solutions offered (no matter how well intentioned)
are not the way to go.
( And as far as 'polite' goes, I do not see
how you could both achieve the 'definitive
statement' and be any more polite.. )
If you have any particular disagreements with
technical aspects of the code provided, discuss
them, otherwise celebrate that you have now
been shown some extra tips.
--
Andrew Thompson
http://www.PhySci.org/ Open-source software suite
http://www.PhySci.org/codes/ Web & IT Help
http://www.1point1C.org/ Science & Technology
|
|
| Back to top |
|
 |
Roedy Green Guest
|
Posted: Thu Apr 29, 2004 9:28 am Post subject: Re: Pausing Threads From Events |
|
|
On Wed, 28 Apr 2004 15:09:18 +0100, Rob Shepherd
<robshep (AT) invalid (DOT) invalid> wrote or quoted :
| Quote: | I'm sorry to tell you the following but you should mostly ignore the
answers you got. These techniques are not professionnal. Period.
So only Java "Professionals" are allowed to post messages with fully working
endorsed guaranteed to work *this-what-you-MUST-do* code examples eh?
|
keep in mind this is comp.lang.java.help THE place for newbies. Cut
everyone some slack.
--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
|
|
| Back to top |
|
 |
Roedy Green Guest
|
Posted: Thu Apr 29, 2004 9:31 am Post subject: Re: Pausing Threads From Events |
|
|
On Wed, 28 Apr 2004 15:30:05 +0100, Ade <ade (AT) here (DOT) invalid> wrote or
quoted :
| Quote: | Is it really necessary to criticize other people's solutions?
YES YES YES. If people post code everyone should be pointing out ways |
to improve it. People learn from copying. If you let sloppy code
pass, you teach sloppy coding. However, there is no need to be nasty.
Engineers and computer scientists have to learn to get ego out the
way. You NEED peer review to get the bugs and and to improve.
Thin skinned people can never become great programmers.
Think of it as a game to polish each bit of code that gets posted to
perfection.
--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|