多线程:2个任务

乔纳斯·奥德纳尔特

我有以下情况:我想运行2个线程:线程A:运行1次的void函数线程B:永无休止的方法

我想再次运行线程A,而不是线程B,再次运行线程A,再次运行线程B,...

但是线程B阻止了线程A,因为它的功能永无止境。有人可以给我一个示例来解决Java中的调度问题吗?

我想要实现的是

  1. 让线程A运行1分钟
  2. 停止线程A
  3. 让线程B运行5秒
  4. 停止线程B
  5. 让线程A运行1分钟
  6. 停止线程A
  7. ...
老弯棍

PauseableThread前一阵子写的-它应该可以满足您的需求。它使用Locks来控制线程的暂停。

而不是写一个,而是Runnable写一个StepperStepper.step()只要没有被告知要暂停,它就会连续呼叫您

/**
 * 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 - i.e. we've been paused.
            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 = () -> {
                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();
            pt.await();
            System.out.println("Finished: " + n);

            // Start again to test agressive cancelling.
            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) {
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

多线程-希望是一个简单的任务

来自分类Dev

多线程不运行任务

来自分类Dev

从2个加入的多线程访问UI线程控件

来自分类Dev

将任务划分为线程-多线程

来自分类Dev

N个线程的多线程

来自分类Dev

在Android中仅运行2个AsyncTask(多线程)

来自分类Dev

用于N个重复任务的多线程体系结构

来自分类Dev

Python多线程如何设置1个池以将任务作为队列运行

来自分类Dev

具有多线程或任务的进程队列

来自分类Dev

多线程在C ++中执行单个任务

来自分类Dev

Java中的多线程任务计划程序

来自分类Dev

如何让多线程处理不同的任务

来自分类Dev

urlib2的多线程

来自分类Dev

Java多线程-6个线程还是30个线程?

来自分类Dev

多线程:两个线程与嵌套线程Python

来自分类Dev

多线程会导致每个任务花费更长的时间吗?

来自分类Dev

多线程/任务差异最小,如何加快处理速度

来自分类Dev

多线程任务以处理C#中的文件

来自分类Dev

vb.net中的多线程模拟任务

来自分类Dev

多线程队列使用者和任务处理

来自分类Dev

支持多线程的带限制的异步任务队列

来自分类Dev

多线程芹菜工作者的任务划分

来自分类Dev

如何实现多线程并并行执行几个任务?

来自分类Dev

多线程队列使用者和任务处理

来自分类Dev

vb.net中的多线程模拟任务

来自分类Dev

使用任务/多线程加载数据并显示UI

来自分类Dev

多线程环境中的任务拆分和处理

来自分类Dev

将任务划分为较小的部分(多线程)

来自分类Dev

我什么时候需要担心导致多线程的任务?