0

设想

比方说,我有这个类,Foo它的唯一工作是顺序执行一组任务。听起来很简单,对吧?好吧,所有这些任务都在各自独立的线程中执行。它不是简单地调用Thread.join()每个任务来确保顺序执行,而是使用 aReentrantLockCondition。例如,

public class Foo
{
    private final Lock lock;
    private final Condition condition;
    private Future<?> task;

    public Foo()
    {
        lock = new ReentrantLock();
        condition = lock.newCondition();

        run();
    }

    /**
     * Runs Foo
     */
    public void run()
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                lock.lock();
                try
                {
                    // do tasks
                }
                finally
                {
                    lock.unlock();
                }

            }
        };

        // Submit task
        task = Executors.newSingleThreadExecutor().submit(runnable);
    }

    /**
     * Blocks execution until signal is received
     */
    public void waitForNotification()
    {
        try
        {
            condition.await();
        }
        catch (InterruptedException e)
        {
        }
    }

    /**
     * Gets the lock
     * 
     * @return Lock
     */
    public final Lock getLock()
    {
        return lock;
    }

    /**
     * Gets the condition
     * 
     * @return Condition
     */
    public final Condition getCondition()
    {
        return condition;
    }

    /**
     * Gets the sender's task
     * 
     * @return Task
     */
    public Future<?> getTask()
    {
        return task;
    }
}

在每个任务之后,waitForNotification()都会调用并等待另一个类,比如说Bar唤醒它。唯一的工作Bar是处理通知应用程序任务是通过还是失败的响应。话虽如此,它将做以下两件事之一:

  1. 完全取消线程(即getTask().cancel
  2. 唤醒线程(即getCondition().signal

第 2 项工作得很好,但第 1 项不行。例如,

public class Bar
{
    private Foo foo;

    // doesn't work!
    public void handleFailed()
    {
        // Cancel task
        foo.getTask().cancel(true)
    }

    public void handlePassed()
    {
         // Signal waiting Foo
         foo.getLock().lock();
         try
         {
            foo.getCondition().signal();
         }
         finally
         {
            foo.getLock().unlock();
         }
    }
}

而不是取消线程,它似乎只是中断了它,这导致它Foo继续执行。抱歉冗长,但我想给你们一个清晰的画面。有什么建议么?

4

2 回答 2

1

除非任务在中断时停止,否则标志将被设置并保持设置,直到任务结束或决定停止。

可能重复http://www.google.co.uk/search?q=how+do+I+stop+a+thread+in+Java 28,000,000 个结果。

于 2011-04-28T14:25:59.443 回答
1

AFAIK,线程不支持开箱即用的“取消”概念。当您的线程被中断时,您必须在逻辑中“取消”您的特定任务。这通常通过在运行任务/作业时检查线程的中断状态来完成,如果状态已设置为 true(当您调用中断时会发生这种情况),则干净地退出。

一个可以帮助你的示例片段。另请阅读,干净地关闭线程

于 2011-04-28T14:50:21.547 回答