通过Java可能的手动启动来处理常规作业

时间:2017-01-10 08:56:43

标签: java multithreading synchronization

我试图解决类似于通过邮件客户端从邮件服务器下载新邮件的问题。我有一个任务,定期执行(例如,下一次迭代是在最后一次结束后10分钟),但也有可能手动运行任务。

当我尝试手动运行作业并且此时作业未运行(稍后指定)时,我取消约会并立即安排。当作业已经运行时,我不会取消它,而是等到它完成并再次运行它。但只有一个任务可以这样等待。

我的问题是我不知道如何同步作业以使其线程安全,并确保作业永远不会同时运行两次。

使其更清晰。主要问题是简单地询问工作是否正在运行并根据我得到的结果做出决定是不够的,因为在问题和行动之间情况可能会发生变化。这是一个短暂的跨度,但概率不是零。同样的问题是决定我是否应该在他的运行结束时再次运行工作。如果我的决定是基于某个变量或其他if子句的值,那么在测试其值和执行某些操作之间,其他一些线程可以更改它,我可以最终得到两个预定作业或者根本没有。

2 个答案:

答案 0 :(得分:0)

您是否考虑过使用DelayQueue

要让您的作业运行now,您只需说服其返回0表单getDelay(TimeUnit unit)

答案 1 :(得分:0)

执行此检查的主要方法是检查,锁定和 之后重复相同的检查

public class OneQueuedThread extends Thread {
    static int numberRunning =0;
    public void run() {
        if (numberRunning<2) {
            synchronized (OneQueuedThread.class){
                if (numberRunning<2) {
                    numberRunning++;
                    // ---------------your process runs here
                    numberRunning--;
                }
            }
        }
    }
}

因此,只有一次尝试在线程运行时运行它将等到正在运行的线程结束并在它之后启动。

至于调度,让我们使用TimerTask功能:

      public class ScheduledTask extends TimerTask {
        ScheduledTask instance;


        /**
         * this constructor is to be used for manual launching
         */
        public void ScheduledTask(){
            if (instance == null){
                instance = this;
            } else {
                instance.cancel();
            }
            instance.run();
        }

        /**
         * This constructor is to be used for scheduled launching
         * @param deltaTime
         */
        public ScheduledTask(long deltaTime){
            instance = this;
            Timer timer = new Timer();
            timer.schedule(instance, deltaTime);

        }

        public void run() {
            OneQueuedThread currentTread;
            currentTread = new OneQueuedThread();
            currentTread.start();
        }
    }