3

我正在尝试执行一个 runnable 几次,如果它没有在 x 秒内完成 3 次,我将取消它。

我用来模拟需要取消任务的情况的代码如下。从输出中我可以看到一个 InterruptedException 被抛出并被相应地捕获,但任务继续运行。

似乎在 TimeoutException 被抛出 3 次之前任务的前两次运行,这两次运行一直运行直到它们完成。我想知道是否有办法阻止这两个运行完成?

public class SomeClass {

private static int c =0;

public static void main(String[] args){
    Runnable dummyRunnable = new Runnable() {

        @Override
        public void run() {
            System.out.println("Hello from dummyRunnable!");        

                for (int i =0; i< 10; i++){
                    try {
                        //simulate work here
                        if (!Thread.currentThread().isInterrupted()) Thread.sleep(5000);
                        System.out.println("thread sleeps for the " + i + " time!");    
                    } catch (InterruptedException ie){
                        System.out.println("InterruptedException catched in dummyRunnable!");   
                        //Thread.currentThread().interrupt(); //this has no effects
                        break;

                    }
                }



        }
    }; 


    BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(10 * 3, true);
    ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, Long.MAX_VALUE, TimeUnit.MILLISECONDS, blockingQueue);

    for (int i =0; i< 5; i++){
        Future<?> task = executor.submit(dummyRunnable);

        try{
            Thread.sleep(1000);
            task.get(2000, TimeUnit.MILLISECONDS);
        } catch (TimeoutException te){
            c++;
            System.out.println("TimeoutException from a task!");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (c==3){
                System.out.println("cancelling task...");
                task.cancel(true);
                break;
            }
        }
    }
     }
}
4

1 回答 1

0

我不明白你实际上想要模拟什么。我希望有一个模拟,比如用卡支付(60 秒超时来完成一项任务),或者可能是医生和病人情况下的秘书。

它现在的方式是在未来创建 5 个对象。如果您想要更多地控制您的线程,您应该考虑使用同步方法和为您处理线程的监视器。

通常在启动线程时,您应该使用

new Thread(new Task(object or generics)).start();
Thread.sleep(2000); // calls this thread to wait 2 secs before doing other task(s)

在做一些核心并发(多线程)之前,你应该阅读一些java教程以获得一些灵感...... http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

于 2013-03-12T00:43:59.553 回答