使用由主线程上的后台线程传递到事件侦听器中的参数

时间:2018-07-23 22:50:22

标签: java multithreading

假设我有这种形式的课程。

class TestClass implements SomeInterface {

    Data myData;

    public TestClass() {
    }

    @Override
    public void onData(Data data) {
        // do stuff with data
        myData = data
    }
}

其中SomeInterface在后​​台线程上进行一些数据处理,并调用onData,后者也在后台线程上运行。我希望能够使用onData线程上的Main返回的数据(更新UI,在主线程上执行其他操作等),因为我确切知道调用后台线程多长时间了,onData将被调用。由于我正在使用某个库中的SomeInterface,因此无法修改此功能(我没有完全按预期使用它)。

在Android中,我本来可以做like this,但是显然没有纯Looper这样的事情,所以在纯Java应用程序中我做不到。从后台线程设置实例变量也不允许我从主线程访问它。

1 个答案:

答案 0 :(得分:0)

您可以发明自己的框架,但这有点愚蠢。 ExecutorServicejava.util.concurrent中的其他类基本上只需要一点点汇编就可以为您完成这一切。

在这里,我在主线程上创建一些输入数据,并使用Callable接口和执行程序将其传递到后台线程。然后,主线程使用Future对象从后台线程获取输出数据。容易。

public abstract class SimpleBackgroundService {

   public static void main( String[] args ) throws InterruptedException, ExecutionException {

      final InputData input = new InputData( 123, "Hi Mom" ); // really should be immutable

      Callable<OutputData> task = new Callable<OutputData>() {
         private final InputData taskInput = input;
         @Override
         public OutputData call() {
            return new OutputData( taskInput );
         }
      };

      ExecutorService es = Executors.newFixedThreadPool( 1 );
      Future<OutputData> taskOutput = es.submit( task );
      // do some stuff here while the task completes.
      OutputData data = taskOutput.get();  // will block and wait if needed
      System.out.println( data );
   }

   static class InputData {

      private final int num;
      private final String msg;

      public InputData( int num, String msg ) {
         this.num = num;
         this.msg = msg;
      }

   }
   static class OutputData {

      private final int num2;
      private final String msg2;

      public OutputData( InputData dat ) {
         num2 = dat.num;
         msg2 = dat.msg;
      }
   }

}