2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.controlloop.tdjam;
23 import java.util.LinkedList;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * This class provides a way to handle synchronization, with minimal blocking. Requests
30 * are queued until {@link #start()} is invoked.
32 public class SerialWorkQueue {
33 private static Logger logger = LoggerFactory.getLogger(SerialWorkQueue.class);
36 private LinkedList<Runnable> workQueue;
39 private boolean running = false;
42 * Constructor - no initial Runnable.
44 public SerialWorkQueue() {
45 workQueue = new LinkedList<>();
49 * Constructor - initial 'Runnable' is specified.
51 * @param runnable an initial 'Runnnable' to run
53 public SerialWorkQueue(Runnable runnable) {
54 workQueue = new LinkedList<>();
55 workQueue.add(runnable);
59 * Starts the queue. If the current thread is the first to start it, then the current
60 * thread will process any requests in the queue before returning.
72 item = workQueue.peekFirst();
81 * Called to add a 'Runnable' to the work queue. If the queue was empty, the current
82 * thread is used to process the queue.
84 * @param work the Runnable to be queued, and eventually run
86 public void queueAndRun(Runnable work) {
89 if (!running || workQueue.size() > 1) {
90 // there was already work in the queue, so presumably there is
91 // already an associated thread running
94 // if we reach this point, the queue was empty when this method was
95 // called, so this thread will process the queue
102 * Internal method to process the work queue until it is empty. Note that entries
103 * could be added by this thread or another one while we are working.
105 * @param firstItem the first item in the queue
107 private void processQueue(Runnable firstItem) {
108 Runnable next = firstItem;
109 while (next != null) {
112 } catch (Exception e) {
113 logger.error("SerialWorkQueue.processQueue exception", e);
116 synchronized (this) {
117 // remove the job we just ran
118 workQueue.removeFirst();
119 next = workQueue.peekFirst();