首页 > 解决方案 > 如何暂停 Runnable() 对象以进行测试

问题描述

我有以下情况:我以这种方式向 NotifyingBlockingThreadPoolExecutor 提交 n 个线程:

while ( index < customers.length ) {
    threadPoolExecutor.submit( new Runnable() {                       
        @Override
        public void run() {
            //callToExternalServiceHere;
            response = mockWebService();
        }
    });
    index++;
}

每个线程都调用一个外部 Web 服务,我们仍然无法使用它。所以我最终创建了一个模拟类,它返回一个包含一些数据的响应。现在我希望能够模拟响应的延迟,我该如何实现这个目标?

提前致谢

更新:

这是我用来实例化 NotifyingBlockingThreadPoolExecutor 的代码

public static NotifyingBlockingThreadPoolExecutor getThreadPoolExecutor() {
    if ( instance.threadPoolExecutor == null ) {
        int numThread = 0;
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        System.out.println( "CheckMultiTransaction - getThreadPoolExecutor - availableProcessors: " + availableProcessors );
        if ( WSConfiguration.getProperty( WSConstants.THREAD_MULTITRN_NUMTHREAD ) != null ) {
            numThread = Integer.parseInt( WSConfiguration.getProperty( WSConstants.THREAD_MULTITRN_NUMTHREAD ) );
            System.out.println( "CheckMultiTransaction - getThreadPoolExecutor - numThread indicati nella S_SYSTEM: " + numThread );
            numThread = numThread > availableProcessors ? availableProcessors : numThread;
        }
        else {
            numThread = availableProcessors;
        }

        System.out.println( "CheckMultiTransaction - getThreadPoolExecutor - numThread : " + numThread );
        int queueSize = numThread * 2; // recommended - twice the size of the poolSize
        int threadKeepAliveTime = 15;
        TimeUnit threadKeepAliveTimeUnit = TimeUnit.SECONDS;

        long maxBlockingTime = 10;
        TimeUnit maxBlockingTimeUnit = TimeUnit.MILLISECONDS;
        boolean useTimeoutQueue = false;
        if ( WSConfiguration.getProperty( WSConstants.THREAD_MULTITRN_MAXBLOCKINGTIME ) != null ) {
            maxBlockingTime = Long.parseLong( WSConfiguration.getProperty( WSConstants.THREAD_MULTITRN_MAXBLOCKINGTIME ) );
            useTimeoutQueue = true;
        }
        final boolean useTimeoutQueueThread = useTimeoutQueue;
        System.out.println( "THREAD_MULTITRN_MAXBLOCKINGTIME:" + WSConfiguration.getProperty( WSConstants.THREAD_MULTITRN_MAXBLOCKINGTIME ) );

        Callable<Boolean> blockingTimeoutCallback = new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                System.out.println( "blockingTimeoutCallback - useTimeoutQueue:" + useTimeoutQueueThread + " - Thread.currentThread().isInterrupted():" + Thread.currentThread().isInterrupted() );
                if ( useTimeoutQueueThread )
                    return false;
                else
                    return !Thread.currentThread().isInterrupted(); // keep waiting
            }
        };

        instance.threadPoolExecutor = new NotifyingBlockingThreadPoolExecutor( numThread, queueSize, threadKeepAliveTime, threadKeepAliveTimeUnit, maxBlockingTime, maxBlockingTimeUnit, blockingTimeoutCallback );
    }
    return instance.threadPoolExecutor;
}

标签: javamultithreadingconcurrencysleep

解决方案


您绝对可以调用方法来延迟 5 秒Thread.sleep(5000)mockWebService()或者只是Thread.sleep(5000)放入Runnable例如

threadPoolExecutor.submit( new Runnable() {                       
        @Override
        public void run() {
            Thread.sleep(5000);
            //callToExternalServiceHere;
            response = mockWebService();
        }
    });

但是,我宁愿推荐你使用一些用于模拟测试的库,例如 Mockito,来创建 Web 服务对象的模拟。在这种情况下,您将能够以更灵活的方式管理模拟 Web 服务的行为。例如,要强制模拟 web 服务做一些延迟,你可以这样做:

Mockito.doAnswer(new Answer() {
   public Object answer(InvocationOnMock invocation) {
       Thread.sleep(<delay_timeout>);
       return "web_service_response_body_object";
   }})
 .when(webServiceMock).doWebServiceCall();

有关更多详细信息,请参阅 Mockito文档Mockito.doAnswer方法文档


推荐阅读