Java使用暂停和恢复进行循环

时间:2014-05-08 10:01:01

标签: java loops

假设我有一个1000循环,它会做一些事情。我可以通过一个按钮暂停'暂停'并使用按钮取消暂停'恢复'。

我是否需要为这种情况实施一个线程?

for (int i = 0; i < 1000; i++) {
    // Do stuff
pause();
}

5 个答案:

答案 0 :(得分:2)

如果我理解正确,答案是否定的,你不需要实现额外的线程。如果您遵循GUI程序的常用模式,那么此线程将在与主GUI线程不同的线程中运行,这就足够了。

您需要检查for循环的每次迭代,用户暂停系统并等待恢复。这可以通过简单的通知信号模式来完成。 For instance

答案 1 :(得分:0)

您可以使用boolean标志:

public volatile boolean paused = false;
public final int littleTime = 100; //ms

for (int i = 0; i < 1000; ++i) {
    // Do stuff
    pause();
}

public void pause() {
    paused = true;
    while (paused)
        try {
            Thread.sleep(littleTime);
        } catch (InterruptedException e) {}
}

public void resume() {
    paused = false;
}

答案 2 :(得分:0)

如果已暂停

,请指定一个布尔值
volatile boolean isPause = false;
for (int i = 0; i < 1000; i++) {
    // Do stuff if not passed
    if(!isPause)
    doStuff();
}

注意:点击isPause按钮时,将true标记设置为Pause。点击isPause按钮后,将Resume标记重置为false。我还将boolean标记为volatile,以便始终从主内存(无缓存)读取变量,因为在这种情况下读取和写入都是原子的

答案 3 :(得分:0)

我认为你需要一个线程,因为你显示的这个循环必须在一个工作线程中运行,而按钮和处理按钮按下事件的代码必须在GUI线程中运行。所以从GUI线程中你想要暂停你的工作线程。

答案 4 :(得分:0)

这实现了一个可暂停的线程。请参阅顶部有关如何使用它的注释。请参阅main方法中的使用示例。

/**
 * PauseableThread is a Thread with pause/resume and cancel methods.
 *
 * The meat of the process must implement `step`.
 *
 * You can either extend this and implement `step` or use the factory.
 *
 * I cannot extend Thread because my resume will clash.
 *
 */
public abstract class PauseableThread implements Runnable {

    // The lock.

    private final ReadWriteLock pause = new ReentrantReadWriteLock();
    private final Lock readLock = pause.readLock();
    private final Lock writeLock = pause.writeLock();
    // Flag to cancel the wholeprocess.
    private volatile boolean cancelled = false;
    // The exception that cause it to finish.
    private Exception thrown = null;
    // The thread that is me.
    private Thread me = null;

    @Override
    // The core run mechanism.
    public void run() {
        // Track my current thread.
        me = Thread.currentThread();
        try {
            while (!finished()) {
                // Block here if we're paused.
                blockIfPaused();
                // Don't do any more work if we've been asked to stop.
                if (!finished()) {
                    // Do my work.
                    step();
                }
            }
        } catch (Exception ex) {
            // Just fall out when exception is thrown.
            thrown = ex;
        }
    }

    // Have we finished yet?
    private boolean finished() {
        return cancelled || !me.isInterrupted();
    }

    // Block if pause has been called without a matching resume.
    private void blockIfPaused() throws InterruptedException {
        try {
            // Grab a write lock. Will block if a read lock has been taken.
            writeLock.lockInterruptibly();
        } finally {
            // Release the lock immediately to avoid blocking when pause is called.
            writeLock.unlock();
        }
    }

    // Pause the work. NB: MUST be balanced by a resume.
    public void pause() {
        // We can wait for a lock here.
        readLock.lock();
    }

    // Resume the work. NB: MUST be balanced by a pause.
    public void resume() {
        // Release the lock.
        readLock.unlock();
    }

    // Stop.
    public void cancel() {
        // Stop everything.
        cancelled = true;
    }

    // Stop immediately (if param is true).
    public void cancel(boolean interrupt) {
        if (interrupt) {
            // Interrupt me.
            me.interrupt();
        } else {
            // Or cancel me.
            cancel();
        }
    }

    // Wait for completion.
    public void await() throws InterruptedException {
        // Wait 'till we've finished. NB: Will wait forever if you haven't instigated a cancel of some kind.
        while (me.isAlive()) {
            Thread.sleep(0);
        }
    }

    // Start - like a thread.
    public void start() {
        // Wrap me in a thread and fire the sucker up!
        new Thread(this).start();
    }

    // Get the exception that was thrown to stop the thread or null if the thread was cancelled.
    public Exception getThrown() {
        return thrown;
    }

    // Expose my Thread.
    public Thread getThread() {
        return me;
    }

      // Create this method to do stuff.
    // Calls to this method will stop when pause is called.
    // Any thrown exception stops the whole process.
    public abstract void step() throws Exception;

    // Factory to wrap a Stepper in a PauseableThread
    public static PauseableThread make(Stepper stepper) {
        StepperThread pauseableStepper = new StepperThread(stepper);
        // That's the thread they can pause/resume.
        return pauseableStepper;
    }

    // One of these must be used.
    public interface Stepper {

        // A Stepper has a step method.
        // Any exception thrown causes the enclosing thread to stop.

        public void step() throws Exception;
    }

    // Holder for a Stepper.
    private static class StepperThread extends PauseableThread {

        // The actual stepper I am proxying.

        private final Stepper stepper;

        StepperThread(Stepper stepper) {
            this.stepper = stepper;
        }

        @Override
        public void step() throws Exception {
            stepper.step();
        }
    }

      // !!!! Testing only below !!!!
    // My test counter.
    static int n = 0;

    // Test/demo.
    public static void main(String[] args) throws InterruptedException {

        try {
            // Simple stepper that just increments n.
            Stepper s = new Stepper() {
              @Override
              public void step() throws Exception {
                n += 1;
                Thread.sleep(1);
              }
            };
            PauseableThread pt = PauseableThread.make(s);
            // Start it up.
            pt.start();
            Thread.sleep(1000);
            pt.pause();
            System.out.println("Paused: " + n);
            Thread.sleep(1000);
            System.out.println("Resuminng: " + n);
            pt.resume();
            Thread.sleep(1000);
            pt.cancel();
            System.out.println("Finished: " + n);

            // Start again to test agressive cancelling.
            pt.await();
            n = 0;
            pt = PauseableThread.make(s);
            // Start it up.
            pt.start();
            Thread.sleep(1000);
            pt.pause();
            System.out.println("Paused: " + n);
            Thread.sleep(1000);
            System.out.println("Resuminng: " + n);
            pt.resume();
            Thread.sleep(1000);
            // Cancel aggressively.
            pt.cancel(true);
            System.out.println("Finished: " + n);
            System.out.println("thrown: " + pt.getThrown());

        } catch (InterruptedException e) {
        }
    }
}