简体   繁体   中英

Java - How to 'return' a value in a class

I am trying to assign a value or return a value in a class. Something like this:

void setOff() {

    boolean onValue = true;

    Thread t = new Thread(new myClass(onValue));

    System.out.println("On: " + onValue);

}

class myClass implements Runnable{

    public boolean on;

    public myClass (boolean _on) {

        on = _on

    }

    public run() {

        on = false;

    }

}

Is something like that possible? Thanks!

It is possible, but you need to change your code a bit. Check the following classes:

The first one is something like a Runnable , but the method you need to implement is defined as V call() throws Exception , instead of void run() : it allows you to return a value.

The second one wraps a Callable<V> (or a Runnable plus a constant return value), and is a Runnable itself, so you can pass it to a Thread just like you were doing with your Runnable .

So, you could change your code to something like the following:

void setOff() {
  final FutureTask<Boolean> ft = new FutureTask<Boolean>(new myClass());
  new Thread(ft).start();
  try {
    System.out.println("The result is: " + ft.get());
  } catch (ExecutionException e) {
    System.err.println("A method executed on the background thread has thrown an exception");
    e.getCause().printStackTrack();
  }
}

class myClass implements Callable<Boolean> {
  @Override public Boolean call() throws Exception {
    // let's fake some long running computation:
    Thread.sleep(1000);
    return true;
  }
}

The call ft.get() will only return after the call() method finishes executing (on the background thread), so you will have to wait 1 second before the line gets printed to the console.

There are many other useful methods on FutureTask . Check the documentation .

There are some other classes that you may find useful: ExecutorService and its implementations, and the factory methods in Executors . It has a method called submit which accepts a Runnable or a Callable<V> , and returns a Future<?> or Future<V> , which is one of the interfaces implemented by FutureTask . You get a similar behaviour. For example:

public static void main() {
  final ExecutorService es = Executors.newCachedThreadPool();
  final Future<Boolean> f = es.submit(new myClass());
  try {
    System.out.println("The result is: " + f.get());
  } catch (ExecutionException e) {
    System.err.println("A method executed on the background thread has thrown an exception");
    e.getCause().printStackTrack();
  }
  es.shutdown();
}

The advantage of this is that the ExecutorService will manage the threads for you. It may create some threads and reuse them for the Callables and Runnables you submit: this will possibly improve performance if you have many such jobs, since you will avoid creating one thread per job -- thread creation has some overhead!

EDIT : the .get() method throws an ExecutionException , which wraps an exception that might get thrown during the execution of the .call() method. To inspect the exception, catch the ExecutionException and call .getCause() on it. I've just added the missing try/catch block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM