polling IRQs in a thread's code

S

Stefan Ram

I am new to multithreading in Java. In a thread's code, I write:

void run()
{ if( irq() )cleanup(); else
{ firstStep();
if( irq() )cleanup1(); else
{ secondStep();
...

The user can request the thread to end using a GUI button.
The thread has to check often whether the user has requested
this, and then has to stop.

Now, all the thread's code is messed up with polling the
status of the user request, before each and every other action.
Writing and maintaining the code is more difficult. I cannot
simply write

void run()
{ firstStep();
secondStep();
...
cleanup(); }

but have to write the code as above.

Is this the usual way to proceed? Or can I simplifiy this somehow?
 
A

Arne Vajhøj

I am new to multithreading in Java. In a thread's code, I write:

void run()
{ if( irq() )cleanup(); else
{ firstStep();
if( irq() )cleanup1(); else
{ secondStep();
...

The user can request the thread to end using a GUI button.
The thread has to check often whether the user has requested
this, and then has to stop.

Now, all the thread's code is messed up with polling the
status of the user request, before each and every other action.
Writing and maintaining the code is more difficult. I cannot
simply write

void run()
{ firstStep();
secondStep();
...
cleanup(); }

but have to write the code as above.

Is this the usual way to proceed? Or can I simplifiy this somehow?

Trying to affect the thread from another thread is known to
cause some problems.

So testing inside the code is common.

I would prefer a more common coding convention though.

public void run() {
...
if(stopflag) { }
...
if(stopflag) { }
...
if(stopflag) { }
...
if(stopflag) { }
...
}

Arne
 
M

markspace

Is this the usual way to proceed? Or can I simplifiy this somehow?

Yes and no. First, I wish you would not use IRQ as your method name.
Interrupt ReQuest is a hardware thing, and we don't have access to those
from within the Java API.

Second, I'd use interrupt(). It's the usual way of asking that a thread
stop. Many routines in the Java API already check for the interrupt
flag for you, which releaves you of some of the burden for testing.
Likewise, wait() and similar fuctions also test for interrupts even when
the thread isn't running, something you would be hard pressed to do.

Third, your code could be structured a little better.


void run()
{
if( irq() ) {
cleanup();
return;
}
firstStep();
if( irq() ) {
cleanup1();
return;
}
secondStep();
if( irq() ) {
cleanup3();
return;
}
...

I hope you see the pattern. Don't use cascading if-else. Just return
from the run() method, it's cleaner. (Several of your braces appeared
to be unbalanced when I corrected the code.) There's probably better
ways of handling the clean-up code, but without more knowledge of what
you are doing, it's hard to say.

Lastly, look at java.util.concurrent.Executor and other frameworks in
the concurrent package. They provide a lot of support for mulithreading.

P. S. Get Java Concurrency In Practice. It's just about required for
working with concurrency in Java.
 
J

John B. Matthews

The user can request the thread to end using a GUI button.
The thread has to check often whether the user has requested
this, and then has to stop.

Also consider SwingWorker<T,V>. You can publish intermediate
results from within your implementation of doInBackground() and
reliably update the GUI from process(), which executes on the EDT.
This related example also illustrates using cancel():

<https://sites.google.com/site/drjohnbmatthews/randomdata>
 
M

markspace

Also consider SwingWorker<T,V>.

That's an excellent point, I completely spaced on the GUI part of his
question. If GUI = Swing, then SwingWorker is an excellent solution to
many problems.

Also, SwingWorkers can be put in executors, and since it returns a
Future, there's a convenient Future#cancel() method to kill the thing
(which does use Thread#interrupt as I suggested earlier).
 
R

Roedy Green

aOn 24 Mar 2013 22:45:47 GMT, (e-mail address removed)-berlin.de (Stefan Ram)
wrote, quoted or indirectly quoted someone who said :
Is this the usual way to proceed? Or can I simplifiy this somehow?

You probably do not have to call your code as frequently as you think.
Once in each loop is probably sufficient, and even then only the
middle loops.

Perhaps you can hide the test in some frequently used code, and throw
an exception.

I second the suggestion of getting Java Concurrency In Practice
http://mindprod.com/book/9780321349606.html for sources
 
M

markspace

void run()
{
if( irq() ) {
cleanup();
return;
}


I posted this, and I didn't much like it when I posted, and now I'm
pretty sure it's rubbish, as they say on the other side of the Atlantic.
SwingWorker got me thinking about better ways to do this.


void run() {
try {
// tons o' stuff
} catch( InterruptedException ex ) {
// clean up
}
}

The trick now is to check for an interrupt often enough. If you're
publishing data periodically with the SwingWorker#publish method, that
might be a good place to check. However you might want to check more
often as well. Either way, throwing an exception seems much easier and
cleaner at the top level than manually breaking your code into discreet
sections.

If you have very complicated clean-up code, you might have to package
the clean-up into discreet chunks so it can be executed by the top level
clean-up code.

class MyTask implements Runnable { // or SwingWorker
private Runnable cleanup;
public void run() {
try {
a();
b();
c();
} catch( InterruptedException ex ) {
if( cleanup != null )
cleanup.run();
}
}
private void a() {
cleanup = new CleanupA();
//... do stuff, then when done, reset cleanup
cleanup = null;
}
private class CleanupA implements Runnable {
public void run() {
// vacuum and dust
}
}
private void b() {
// etc.
}
private void c() {
// etc.
}
}

That seems cleaner to look at, at least for what's written there.

If you do use Runnable, don't overlook this simple transform to get a
more modern version.

Future<X> future = new FutureTask( myTask, x );
 
E

Eric Sosman

[...]
Either way, throwing an exception seems much easier and
cleaner at the top level than manually breaking your code into discreet
sections.

From http://www.merriam-webster.com/dictionary/discreet

Definition of DISCREET
1 : having or showing discernment or good judgment
in conduct and especially in speech : prudent;
especially : capable of preserving prudent silence
2: unpretentious, modest <the warmth and discreet
elegance of a civilized home — Joseph Wechsberg>
3: unobtrusive, unnoticeable <followed at a discreet
distance>

See also http://www.merriam-webster.com/dictionary/discrete

Coming attractions: "loose" and "lose" ;-)
 
R

Robert Klemme

Yes and no. First, I wish you would not use IRQ as your method name.
Interrupt ReQuest is a hardware thing, and we don't have access to those
from within the Java API.

Second, I'd use interrupt(). It's the usual way of asking that a thread
stop. Many routines in the Java API already check for the interrupt
flag for you, which releaves you of some of the burden for testing.
Likewise, wait() and similar fuctions also test for interrupts even when
the thread isn't running, something you would be hard pressed to do.

That can also be viewed as a downside: you loose control over when the
process may be interrupted. If you only want to allow for interruption
at certain steps in the process then interrupt() might actually be unusable.
Third, your code could be structured a little better.

Another structure could be:

private final List<Task> tasks = ...
private volatile boolean run;

public void run() {
run = true;

for (final Task t : tasks) {
t.execute();

if (!run) {
cleanup();
return;
}
}
}

or even

public void run() {
run = true;

for (final Task t : tasks) {
if (run) {
t.execute();
}
else {
t.ignore();
}
}
}
P. S. Get Java Concurrency In Practice. It's just about required for
working with concurrency in Java.

+1

Kind regards

robert
 
E

Eric Sosman

[...]
That can also be viewed as a downside: you loose control over when the
process may be interrupted.[...]

Elsethread I wrote
Coming attractions: "loose" and "lose" ;-)

.... and on the principle of "Never threaten what you're not
prepared to do," I guess my hand is forced.

From http://www.merriam-webster.com/dictionary/loose

Definition of LOOSE
transitive verb
1a: to let loose (see 1 loose): release
b: to free from restraint
2: to make loose : untie <loose a knot>
3: to cast loose : detach
4: to let fly : discharge
5: to make less rigid, tight, or strict : relax
intransitive verb
: to let fly a missile (as an arrow) : fire

See also http://www.merriam-webster.com/dictionary/lose

Coming attractions: "then" and "than" :-(

(Aside: Of the few languages I know, English is by far the
most idiosyncratic, anti-systemic, and downright perverse.
Toddlers' brains are said to be "wired" for learning language;
an adult whose wiring has fallen away and who yet manages to
learn English, even imperfectly, has my admiration and no
little of my awe.)
 
R

Robert Klemme

[...]
That can also be viewed as a downside: you loose control over when the
process may be interrupted.[...]

Elsethread I wrote
Coming attractions: "loose" and "lose" ;-)
LOOL

Coming attractions: "then" and "than" :-(

You could throw "thin" in the mix. ;-)
(Aside: Of the few languages I know, English is by far the
most idiosyncratic, anti-systemic, and downright perverse.
Toddlers' brains are said to be "wired" for learning language;
an adult whose wiring has fallen away and who yet manages to
learn English, even imperfectly, has my admiration and no
little of my awe.)

:)

Cheers

robert
 
G

Gene Wirchenko

[...]
Either way, throwing an exception seems much easier and
cleaner at the top level than manually breaking your code into discreet
sections.

From http://www.merriam-webster.com/dictionary/discreet

Definition of DISCREET
1 : having or showing discernment or good judgment
in conduct and especially in speech : prudent;
especially : capable of preserving prudent silence
2: unpretentious, modest <the warmth and discreet
elegance of a civilized home — Joseph Wechsberg>
3: unobtrusive, unnoticeable <followed at a discreet
distance>

See also http://www.merriam-webster.com/dictionary/discrete

Coming attractions: "loose" and "lose" ;-)

And "prescribe" and "proscribe".

Sincerely,

Gene Wirchenko
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top