FutureCallback从未执行过

时间:2018-03-08 15:07:38

标签: java api asynchronous guava future

我试图从Guava中获取FutureCallbacks,因为我想在我的java api中使用它来获得cloudflare。

测试类:

import com.google.common.util.concurrent.*;

import javax.annotation.Nullable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

    @org.junit.Test

    public static void apiUsersCode( ) {
        apiMethodThatReturnsCloudflareInfos( new FutureCallback<String>() {
            @Override
            public void onSuccess( @Nullable String result ) {
                System.out.println( "WORKING" );
            }

            @Override
            public void onFailure( Throwable t ) {
                System.out.println( t );
            }
        } );
    }

    public static void apiMethodThatReturnsCloudflareInfos( FutureCallback<String> usersFutureCallback ) {
        Callable<String> solution = ( ) -> {
            Thread.sleep( 1000L ); // simulate slowness of next line
            return "http output"; // this is this other method that sends a http request
        };

        // runs callable async, when done: execute usersFutureCallback
        ExecutorService executor = Executors.newFixedThreadPool( 10 );
        ListeningExecutorService service = MoreExecutors.listeningDecorator( executor );
        ListenableFuture<String> listenableFuture = service.submit( solution );
        Futures.addCallback( listenableFuture, usersFutureCallback, service );
    }
}

当有人使用此api简化时:

  1. 他调用一个方法并传递一个FutureCallback对象(usersFutureCallback)
  2. 此方法运行另一种方法,其输出以可调用的
  3. 返回
  4. 完成
  5. 由用户执行的示例Api方法

    apiMethodThatReturnsCloudflareInfos( new FutureCallback<String>() {
        @Override
        public void onSuccess( @Nullable String cloudflareOutput ) {
            System.out.println( "WORKING" );
        }
    
        @Override
        public void onFailure( Throwable t ) {
            System.out.println( t );
        }
    } );
    

    示例api方法简化

    public static void apiMethodThatReturnsCloudflareInfos( FutureCallback<String> usersFutureCallback ) {
        Callable<String> solution = ( ) -> {
            Thread.sleep( 1000L ); // simulate slowness of next line
            return "http output"; // this is this other method that sends a http request
        };
    
        // runs callable async, when done: execute usersFutureCallback
        ExecutorService executor = Executors.newFixedThreadPool( 10 );
        ListeningExecutorService service = MoreExecutors.listeningDecorator( executor );
        ListenableFuture<String> listenableFuture = service.submit( solution );
        Futures.addCallback( listenableFuture, usersFutureCallback, service );
    }
    

    &#34;工作&#34;仅在更改和添加此行以在可调用完成后添加侦听器时打印。 但这不是原因的解决方案。

    public static void apiMethodThatReturnsCloudflareInfos( FutureCallback<String> usersFutureCallback ) {
        Callable<String> solution = ( ) -> {
            Thread.sleep( 1000L ); // simulate slowness of next line
            return "http output"; // this is this other method that sends a http request
        };
    
        // runs callable async, when done: execute usersFutureCallback
        ExecutorService executor = Executors.newFixedThreadPool( 10 );
        ListeningExecutorService service = MoreExecutors.listeningDecorator( executor );
        ListenableFuture<String> listenableFuture = service.submit( solution );
    
        // i don't want that
        try {
            Thread.sleep( 10001L );
        } catch ( InterruptedException e ) {
            e.printStackTrace();
        }
    
        Futures.addCallback( listenableFuture, usersFutureCallback, service );
    }
    

    我做错了什么?

2 个答案:

答案 0 :(得分:0)

问题在于您如何测试该方法。你基本上创建一个运行你的Callable<String> solution的新线程,但没有什么会等待该线程完成。一旦您的测试方法完成,您的测试套件将终止并使用正在运行的线程solution

在现实生活中,您的应用程序的使用寿命超过solution,您将无法遇到此问题。

要解决此问题,您必须更新测试用例,以免过早终止。您可以通过更新apiUsersCode()来设置onSuccessonFailure中的某个值,并在调用apiMethodThatReturnsCloudflareInfos后等待。{/ p>

答案 1 :(得分:0)

<强>解决!

问题是测试套装JUnit。 它在main(String [] args)方法中测试时有效。

......一切都是正确的只有应该帮助我进行测试的错误:D

Query lastmess = FirebaseDatabase.getInstance().getReference("Messages").child(my_Id).child(sendUID);
lastmess.orderByKey().limitToLast(1).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataa) {
        for (DataSnapshot snap : dataa.getChildren()) {
            MessModel messages = snap.getValue(MessModel.class);
            String mes = messages.getMessage(); //here I can get the last message
            messages.setMessage("updated Message"); //here is the problem , why it doesn't work ?
        }
    }

    @Override
        public void onCancelled(DatabaseError databaseError) {
    }
});