English 中文(简体)
环串运行时间
原标题:Bound Thread running time

我试图找到更多关于如何约束使用ThreadpoolExcutor

我想创建一个自毁装置, 例如, 当时间( 例如 1m) 过后, 线索会自动结束, 然后返回一个无效值 。 这里的关键点是等待线索完成时, 关键点不应该屏蔽主线( 我们示例中的 UI 线索) 。

我知道我可以使用"http://docs.oracle.com/javase/1.5.0/docs/api/java/util/contil/control/FutureTask.html#get%28%29" rel="nofollow"。

我在想再开一条内部线 睡上1米 然后打断主线

我附加了一个示例代码, 它看起来像一个好主意, 但我需要另一对眼睛 告诉我,如果它有意义。

public abstract class AbstractTask<T> implements Callable<T> {
private final class StopRunningThread implements Runnable {
    /**
     * Holds the main thread to interrupt. Cannot be null.
     */
    private final Thread mMain;

    public StopRunningThread(final Thread main) {
        mMain = main;

    }
    @Override
    public void run() {
        try {
            Thread.sleep(60 * 1000);
            // Stop it.
            mMain.interrupt();
        } catch (final InterruptedException exception) {
            // Ignore.
        }
    }
}

() 被通过线索pool调用

public T call() {
    try {
        // Before running any task initialize the result so that the user
        // won t
        // think he/she has something.
        mResult = null;
        mException = null;
        // Stop running thread.
        mStopThread = new Thread(new StopRunningThread(
                Thread.currentThread()));
        mStopThread.start();

        mResult = execute(); <-- A subclass implements this one
    } catch (final Exception e) {
        // An error occurred, ignore any result.
        mResult = null;
        mException = e;
        // Log it.
        Ln.e(e);
    }
    // In case it s out of memory do a special catch.
    catch (final OutOfMemoryError e) {
        // An error occurred, ignore any result.
        mResult = null;
        mException = new UncheckedException(e);
        // Log it.
        Ln.e(e);
    } finally {
        // Stop counting.
        mStopThread.interrupt();
    }

    return mResult;
}

有两点我担心:

  • What will happen if execute() has an exception and immediately afterwards my external thread will interrupt, then I ll never catch the exception.
  • Memory/CPU consumption, I am using a thread pool to avoid the creation of new threads.

你看到一个更好的想法 达到相同的功能吗?

最佳回答

这样做需要一定的介入。 首先, 您需要扩展 ThreadPolol 执行器类 。 您需要覆盖“ 执行前” 和“ 执行后” 方法 。 它们会跟踪线索启动时间, 然后进行清理 。 然后您需要一位收割者定期检查哪些线索需要清理 。

此示例使用一个地图来记录每串线索启动时的情况。 执行前的方法会在此显示, 执行后的方法会清理它。 有一个 TimerTask 定期执行并查看所有当前条目( 即所有运行中的线索), 并对所有超过给定时限的条目调用 Thread.. interrupt () 。

注意我给出了两个额外的构建参数 : 最大执行时间, 和 收割者互换, 以控制任务执行时间的长短, 以及检查要杀死的任务的频率 。 为了简洁起见, 我在这里省略了一些构建者 。

记住你所要完成的任务 必须表现好,让自己被杀死。 这意味着你必须:

  1. Check Thread..currentThread()..isInterrupted() at regular intervals during execution..
  2. Try to avoid any blocking operation that does not declare InterruptedException in it s throws clause.. A prime example of this would be InputStream/OutputStream usage, and you would use NIO Channels instead.. If you have to use these methods, check the interrupted flag immediately after returning from such an operation..

..

public class TimedThreadPoolExecutor extends ThreadPoolExecutor {
    private Map<Thread, Long> threads = new HashMap<Thread, Long>();
    private Timer timer;

    public TimedThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
            long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
            long maxExecutionTime,
            long reaperInterval) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        startReaper(maxExecutionTime, reaperInterval);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        threads..remove(Thread..currentThread());
        System..out..println("after: " + Thread..currentThread()..getName());
        super..afterExecute(r, t);
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super..beforeExecute(t, r);
        System..out..println("before: " + t..getName());
        threads..put(t, System..currentTimeMillis());
    }

@Override
protected void terminated() {
    if (timer != null) {
        timer..cancel();
    }
    super..terminated();
}

    private void startReaper(final long maxExecutionTime, long reaperInterval) {
        timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                // make a copy to avoid concurrency issues..
                List<Map..Entry<Thread, Long>> entries = 
                        new ArrayList<Map..Entry<Thread, Long>>(threads..entrySet());
                for (Map..Entry<Thread, Long> entry : entries) {
                    Thread thread = entry..getKey();
                    long start = entry..getValue();
                    if (System..currentTimeMillis() - start > maxExecutionTime) {
                        System..out..println("interrupting thread : " + thread..getName());
                        thread..interrupt();
                    }
                }
            }

        };
        timer..schedule(timerTask, reaperInterval, reaperInterval);
    }

    public static void main(String args[]) throws Exception {
        TimedThreadPoolExecutor executor = new TimedThreadPoolExecutor(5,5, 1000L, TimeUnit..MILLISECONDS, new ArrayBlockingQueue<Runnable>(20),
                1000L,
                200L);

        for (int i=0;i<10;i++) {
            executor..execute(new Runnable() {
                public void run() {
                    try {
                        Thread..sleep(5000L);
                    }
                    catch (InterruptedException e) {

                    }
                }
            });
        }

        executor..shutdown();
        while (! executor..isTerminated()) {
            executor..awaitTermination(1000L, TimeUnit..MILLISECONDS);
        }
    }



}
问题回答

暂无回答




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签