同步处理排队对象

时间:2015-06-12 13:06:41

标签: java multithreading synchronization message-queue queueing

我有一个队列,插入和处理新对象。为了处理我使用可以结束并且可以重新启动的单线程。

private Thread backgroundThread;
private final Queue<ImgData> queuedImgs = new LinkedList<>();

public void scheduleNewCodeImg(ImgData imgData) {
    LOG.log(Level.INFO, "entering{0}", new Object[]{imgData});
    queuedImgs.add(imgData);
}

public void createAndSetImgs() {
    if (backgroundThread == null || !backgroundThread.isAlive()) {
        LOG.log(Level.INFO, "starting thread proces for creating codeImgs");
        backgroundThread = new Thread(new ExecutionThread(0, true) {

            @Override
            protected boolean process() {
                if (!queuedImgs.isEmpty()) {
                    ImgData imgData = queuedImgs.poll();
                    if (imgData != null) {

                        saveImg(imgData);

                        return true;
                    }
                }

                return false;
            }
        }, "CodeImgOnS3CreatorThread");
        backgroundThread.start();
    }
}

private void saveImg(final ImgData imgData) {
    //do smthng
}

我的runnable接口的实现提供了抽象process方法,并反复检查有限量的迭代方法返回值。如果为true,则进程重置为从开始时开始:

public abstract class ExecutionThread implements Runnable {

private static final Logger LOG = Logger.getLogger(ExecutionThread.class.getName());

private final int baseDelayInSeconds;
private final boolean uniformDelayGrowth;
private static final int DEFAULT_DELAY_SECONDS = 5; // for 5 the calculated iterationDelays are 1,1,1,5,5,5,25,25,25
private static final int ITERATIONS_COUNT = 3;
private static final int STEPS_COUNT = 3;

public ExecutionThread() {
    this.baseDelayInSeconds = DEFAULT_DELAY_SECONDS;
    this.uniformDelayGrowth = false;
}

public ExecutionThread(int baseDelayInSeconds, boolean uniformDelayGrowth) {
    this.baseDelayInSeconds = baseDelayInSeconds;
    this.uniformDelayGrowth = uniformDelayGrowth;
}

@Override
public final void run() {
    LOG.log(Level.INFO, "running new ExecutionThread");
    int step = 0;
    while (step < STEPS_COUNT) {
        for (int iteration = 0; iteration < ITERATIONS_COUNT; iteration++) {

            try {
                if (this.baseDelayInSeconds > 0) {
                    if (uniformDelayGrowth) {
                        Thread.sleep(this.baseDelayInSeconds * 1000);
                    } else {
                        long iterationDelay = (long) Math.pow(this.baseDelayInSeconds, step) * 1000;
                        Thread.sleep(iterationDelay);
                    }
                } else {
                    Thread.sleep(10); //minimal processing timeout to provide time for finishing tasks to end
                }
            } catch (InterruptedException ex) {
                LOG.log(Level.SEVERE, "thread sleep was interrupted: ", ex);
            }

            if (process()) {
                step = 0;
                iteration = 0;
            }
        }
        step++;
    }
}

/**
 *
 * @return true if iterations should be reset from start, else false
 */
    protected abstract boolean process();

}

用法如下(简化)

instance = new InstanceOfService();
instance.scheduleNewCodeImg(imgObj);
instance.createAndSetImgs();

我怀疑在最后一次迭代结束的那一刻,可能会有一些错误没有处理插入的项目。 我考虑过一些同步,但我不确定同步这两种方法会有所帮助,因为该过程在backgrounf线程中运行。 你能指点我怎么解决这个问题吗?

0 个答案:

没有答案