Using a Thread to return from a method

J

James Gralton

Hi all,

I have a question and am not sure if it is even possible but would appreciate any advice. First I
will show my small self contained example of my issue. This isn't my application just a very
simplistic view of what I am trying to achieve.

public class Main {

public static void main(String[] args) {
Main m = new Main(true);
}

public Main(boolean flag){
this.flag = flag;
}

private boolean flag = false;

private boolean terminate = false;

public void setTerminate(boolean terminate){
this.terminate = terminate;
}

public void Task1(){
Thread t = new Thread(new Runnable() {
public void run() {
while(!terminate){
try{
Thread.sleep(1000);
}
catch(Exception e){
e.printStackTrace();
}
}
//If I get here I want to return from task 1 regardeless of whether
//Tasks 2, 3 or 4 have finished.

}
});
System.out.println("Doing Task 1");
}

public void Task2(){
System.out.println("Doing Task 2");

if(flag){

}
else{

}
}

public void Task3(){
for(int i=0;i<5;i++){
System.out.println("Doing Task 3");
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}

public void Task4(){
for(int i=0;i<7;i++){
System.out.println("Doing Task 4");
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}
}


Essentially what I would like to to is kick of a Thread in Task1 which monitors a terminate flag
which is set elsewhere in my application (set when a user wants to cancel a long operation). When
the terminate flag is set I would like to stop the tasks I am performing (regardless of whether I am
currently executing Task 2, 3 or 4 in the chain) and return from Task1 to the calling method. I
can't simply System.exit() as the user will likely have cancelled the operation so they can carry on
with something else in the application.

Is there anyway of doing this?

All help/advice is gratefully appreciated.

James
 
I

Ingo R. Homann

Hi,

James said:
Essentially what I would like to to is kick of a Thread in Task1 which
monitors a terminate flag which is set elsewhere in my application (set
when a user wants to cancel a long operation). When the terminate flag
is set I would like to stop the tasks I am performing (regardless of
whether I am currently executing Task 2, 3 or 4 in the chain)

If I understand you correctly, this is, what your code is already
correctly doing.
and return
from Task1 to the calling method.

A Thread does not return to his "caller" because it is exactly what it
is *not* supposed top to: There is no "caller", only someone who started
the Thread. If this "someone" should wait until the Task is done, the
Task sould not be started in a Thread (although it can start it and then
call t.join() but that does not make sense)!
I can't simply System.exit() as the
user will likely have cancelled the operation so they can carry on with
something else in the application.

I think, I understand what you mean. Well, you can leave the Thread
without thinking about it. The other Threads will continue running. The
Application only terminates, when there is no (non-daemon) Thread left.
See the doku to Thread#setDaemon() for more details.

Ciao,
Ingo
 
C

Cantankerous Old Git

James said:
Hi all,

I have a question and am not sure if it is even possible but would
appreciate any advice. First I will show my small self contained example
of my issue. This isn't my application just a very simplistic view of
what I am trying to achieve.

public class Main {

public static void main(String[] args) {
Main m = new Main(true);
}

public Main(boolean flag){
this.flag = flag;
}

private boolean flag = false;

private boolean terminate = false;

public void setTerminate(boolean terminate){
this.terminate = terminate;
}

public void Task1(){
Thread t = new Thread(new Runnable() {
public void run() {
while(!terminate){
try{
Thread.sleep(1000);
}
catch(Exception e){
e.printStackTrace();
}
}
//If I get here I want to return from task 1 regardeless
of whether
//Tasks 2, 3 or 4 have finished.

}
});
System.out.println("Doing Task 1");
}

public void Task2(){
System.out.println("Doing Task 2");

if(flag){

}
else{

}
}

public void Task3(){
for(int i=0;i<5;i++){
System.out.println("Doing Task 3");
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}

public void Task4(){
for(int i=0;i<7;i++){
System.out.println("Doing Task 4");
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}
}


Essentially what I would like to to is kick of a Thread in Task1 which
monitors a terminate flag which is set elsewhere in my application (set
when a user wants to cancel a long operation). When the terminate flag
is set I would like to stop the tasks I am performing (regardless of
whether I am currently executing Task 2, 3 or 4 in the chain) and return
from Task1 to the calling method. I can't simply System.exit() as the
user will likely have cancelled the operation so they can carry on with
something else in the application.

Is there anyway of doing this?

All help/advice is gratefully appreciated.

James

I think you need to explain a little more - I don't understand
what your problem is.

In your example code, nothing calls any of the task methods.

Ignoring that, consider this:
* Anything that called task1() would launch a new thread that
enters the run() method indefinitely.
* Whatever called task1() would return immediately (milliseconds)
after launching the new thread thread.
* The new thread will return from the run() method and die soon
after the terminate flag is set. It doesn't return to any of your
code, it returns to the VM that birthed it at your request.

This is a bit like hiring a cleaner to clean your house. Having
placed the order, you don't have to stay on the phone until the
house is clean, you put the phone down and get on with your life,
confident that the job will get done. And after the house is
clean, you don't expect the cleaner to return to YOUR bed.

task2, 3 and 4 methods don't appear to test the terminate flag,
so they will not know they have to return early. But it is not
unusual to put a test for a cancel flag inside long-running
loops, as you have in the run() method of the Runnable.

When thinking about threads buzzing around into and out of the
methods of different objects, I find it helpful to use the image
of lots of filing klerks flitting between desks piled with large
dusty ledgers (or engineers between workbenches), fiddling and
making notes or adjustments before moving on to the next place.

Hopefully this makes at least some sense.

The Cog
 

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,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top