How do I get results from my work queue task?
I've implemented a simply work queue that receives tasks from a number of different threads. I want these tasks to return a value to their source thread, but can't figure out how to do that.
I've considered using a future, but there's no way to explicitly set the future's value. I could use a property, but I don't believe those are thread safe.
Every task is an implementation of DBRequest. The actual content varies, but the result of all activities is a string.
An asynchronous thread creates a DBRequest and submits it to the queue. The queue runs the task, which produces a string. How do I get that string back to the thread that created the DBRequest, and how can I cause my creator thread to wait for the result?
public interface DBRequest
String execute(VdtsSysDB vdtsSysDB, BoardLoad currentLoad);
public class DBQueue implements Runnable
private static DBQueue dbQueue;
private LinkedBlockingQueue<DBRequest> queue = new LinkedBlockingQueue<>();
private VdtsSysDB vdtsSysDB = new VdtsSysDB();
private ReentrantLock lock = new ReentrantLock();
private static final Logger LOG = LoggerFactory.getLogger(DBQueue.class);
private boolean kill = false;
private BoardLoad currentLoad;
private ProgressController progressController;
public static DBQueue getInstance()
if (dbQueue == null) synchronized (DBQueue.class)
if (dbQueue == null)
dbQueue = new DBQueue();
return dbQueue;
private DBQueue()
public ReentrantLock getLock()
return lock;
@Override
public void run()
LOG.info("Starting DBQueue loop. Kill .", kill);
while (!kill)
DBRequest dbRequest = removeRequest();
if (dbRequest != null)
lock.lock();
String result = dbRequest.execute(vdtsSysDB, currentLoad);
lock.unlock();
if (progressController != null) Platform.runLater(() ->
progressController.updateDisplay(currentLoad));
vdtsSysDB.getEntityManager().close();
public void addRequest(DBRequest dbRequest)
try
queue.add(dbRequest);
LOG.info("Added request.");
catch (Exception e)
LOG.error("Can't add element.", e);
private DBRequest removeRequest()
DBRequest result = null;
try
//result = queue.poll(10, TimeUnit.SECONDS);
result = queue.take();
catch (Exception e)
LOG.error("Exception.", e);
return result;
public void killDBQueue()
kill = true;
LOG.info("Shutting down DBQueue.");
public static void start()
Thread thread = new Thread(DBQueue.getInstance(), "DBQueue Thread");
thread.start();
LOG.info("Starting DBQueue.");
public BoardLoad getCurrentLoad()
if (currentLoad == null)
currentLoad = BoardLoad.getLastOpenLoad(vdtsSysDB);
return currentLoad;
public void setCurrentLoad(BoardLoad proposedLoad)
// We can only have one open load, and by definition, the current load is open. So close it.
if (this.currentLoad != null && !this.currentLoad.equals(proposedLoad))
currentLoad.close(vdtsSysDB);
if (proposedLoad != null)
this.currentLoad = vdtsSysDB.getEntityManager().find(BoardLoad.class, proposedLoad.getId());
else this.currentLoad = null;
public ProgressController getProgressController()
return progressController;
public void setProgressController(ProgressController progressController)
this.progressController = progressController;
EDIT: I'm using this queue to synchronize database access, reducing the need for locks and ensuring that requests are completed sequentially. I don't believe there is any other way to achieve this sort of asynchronous request -> synchronous request change.
But I'd love to have that belief changed.
java multithreading java-8
add a comment |
I've implemented a simply work queue that receives tasks from a number of different threads. I want these tasks to return a value to their source thread, but can't figure out how to do that.
I've considered using a future, but there's no way to explicitly set the future's value. I could use a property, but I don't believe those are thread safe.
Every task is an implementation of DBRequest. The actual content varies, but the result of all activities is a string.
An asynchronous thread creates a DBRequest and submits it to the queue. The queue runs the task, which produces a string. How do I get that string back to the thread that created the DBRequest, and how can I cause my creator thread to wait for the result?
public interface DBRequest
String execute(VdtsSysDB vdtsSysDB, BoardLoad currentLoad);
public class DBQueue implements Runnable
private static DBQueue dbQueue;
private LinkedBlockingQueue<DBRequest> queue = new LinkedBlockingQueue<>();
private VdtsSysDB vdtsSysDB = new VdtsSysDB();
private ReentrantLock lock = new ReentrantLock();
private static final Logger LOG = LoggerFactory.getLogger(DBQueue.class);
private boolean kill = false;
private BoardLoad currentLoad;
private ProgressController progressController;
public static DBQueue getInstance()
if (dbQueue == null) synchronized (DBQueue.class)
if (dbQueue == null)
dbQueue = new DBQueue();
return dbQueue;
private DBQueue()
public ReentrantLock getLock()
return lock;
@Override
public void run()
LOG.info("Starting DBQueue loop. Kill .", kill);
while (!kill)
DBRequest dbRequest = removeRequest();
if (dbRequest != null)
lock.lock();
String result = dbRequest.execute(vdtsSysDB, currentLoad);
lock.unlock();
if (progressController != null) Platform.runLater(() ->
progressController.updateDisplay(currentLoad));
vdtsSysDB.getEntityManager().close();
public void addRequest(DBRequest dbRequest)
try
queue.add(dbRequest);
LOG.info("Added request.");
catch (Exception e)
LOG.error("Can't add element.", e);
private DBRequest removeRequest()
DBRequest result = null;
try
//result = queue.poll(10, TimeUnit.SECONDS);
result = queue.take();
catch (Exception e)
LOG.error("Exception.", e);
return result;
public void killDBQueue()
kill = true;
LOG.info("Shutting down DBQueue.");
public static void start()
Thread thread = new Thread(DBQueue.getInstance(), "DBQueue Thread");
thread.start();
LOG.info("Starting DBQueue.");
public BoardLoad getCurrentLoad()
if (currentLoad == null)
currentLoad = BoardLoad.getLastOpenLoad(vdtsSysDB);
return currentLoad;
public void setCurrentLoad(BoardLoad proposedLoad)
// We can only have one open load, and by definition, the current load is open. So close it.
if (this.currentLoad != null && !this.currentLoad.equals(proposedLoad))
currentLoad.close(vdtsSysDB);
if (proposedLoad != null)
this.currentLoad = vdtsSysDB.getEntityManager().find(BoardLoad.class, proposedLoad.getId());
else this.currentLoad = null;
public ProgressController getProgressController()
return progressController;
public void setProgressController(ProgressController progressController)
this.progressController = progressController;
EDIT: I'm using this queue to synchronize database access, reducing the need for locks and ensuring that requests are completed sequentially. I don't believe there is any other way to achieve this sort of asynchronous request -> synchronous request change.
But I'd love to have that belief changed.
java multithreading java-8
CompletableFutureprovides a way to set a future's value.
– teppic
Nov 13 '18 at 20:27
You might want to run this by codereview. There are quite a few synchronisation problems in your code.
– teppic
Nov 13 '18 at 20:28
1
Your queue sounds likeExecutorServicenot a queue. You can submit tasks toExecutorServicewhich returnsFutureback. So thread that submits task to execute can callFuture.get()to wait for result.
– Ivan
Nov 13 '18 at 20:31
1
@teppic Please do not refer questions with broken code to Code Review. The cross-post is likely to be closed as off-topic.
– 200_success
Nov 13 '18 at 21:28
@200_success. Ah. My apologies. I was unaware of the protocol.
– M. Teasdale
Nov 13 '18 at 21:45
add a comment |
I've implemented a simply work queue that receives tasks from a number of different threads. I want these tasks to return a value to their source thread, but can't figure out how to do that.
I've considered using a future, but there's no way to explicitly set the future's value. I could use a property, but I don't believe those are thread safe.
Every task is an implementation of DBRequest. The actual content varies, but the result of all activities is a string.
An asynchronous thread creates a DBRequest and submits it to the queue. The queue runs the task, which produces a string. How do I get that string back to the thread that created the DBRequest, and how can I cause my creator thread to wait for the result?
public interface DBRequest
String execute(VdtsSysDB vdtsSysDB, BoardLoad currentLoad);
public class DBQueue implements Runnable
private static DBQueue dbQueue;
private LinkedBlockingQueue<DBRequest> queue = new LinkedBlockingQueue<>();
private VdtsSysDB vdtsSysDB = new VdtsSysDB();
private ReentrantLock lock = new ReentrantLock();
private static final Logger LOG = LoggerFactory.getLogger(DBQueue.class);
private boolean kill = false;
private BoardLoad currentLoad;
private ProgressController progressController;
public static DBQueue getInstance()
if (dbQueue == null) synchronized (DBQueue.class)
if (dbQueue == null)
dbQueue = new DBQueue();
return dbQueue;
private DBQueue()
public ReentrantLock getLock()
return lock;
@Override
public void run()
LOG.info("Starting DBQueue loop. Kill .", kill);
while (!kill)
DBRequest dbRequest = removeRequest();
if (dbRequest != null)
lock.lock();
String result = dbRequest.execute(vdtsSysDB, currentLoad);
lock.unlock();
if (progressController != null) Platform.runLater(() ->
progressController.updateDisplay(currentLoad));
vdtsSysDB.getEntityManager().close();
public void addRequest(DBRequest dbRequest)
try
queue.add(dbRequest);
LOG.info("Added request.");
catch (Exception e)
LOG.error("Can't add element.", e);
private DBRequest removeRequest()
DBRequest result = null;
try
//result = queue.poll(10, TimeUnit.SECONDS);
result = queue.take();
catch (Exception e)
LOG.error("Exception.", e);
return result;
public void killDBQueue()
kill = true;
LOG.info("Shutting down DBQueue.");
public static void start()
Thread thread = new Thread(DBQueue.getInstance(), "DBQueue Thread");
thread.start();
LOG.info("Starting DBQueue.");
public BoardLoad getCurrentLoad()
if (currentLoad == null)
currentLoad = BoardLoad.getLastOpenLoad(vdtsSysDB);
return currentLoad;
public void setCurrentLoad(BoardLoad proposedLoad)
// We can only have one open load, and by definition, the current load is open. So close it.
if (this.currentLoad != null && !this.currentLoad.equals(proposedLoad))
currentLoad.close(vdtsSysDB);
if (proposedLoad != null)
this.currentLoad = vdtsSysDB.getEntityManager().find(BoardLoad.class, proposedLoad.getId());
else this.currentLoad = null;
public ProgressController getProgressController()
return progressController;
public void setProgressController(ProgressController progressController)
this.progressController = progressController;
EDIT: I'm using this queue to synchronize database access, reducing the need for locks and ensuring that requests are completed sequentially. I don't believe there is any other way to achieve this sort of asynchronous request -> synchronous request change.
But I'd love to have that belief changed.
java multithreading java-8
I've implemented a simply work queue that receives tasks from a number of different threads. I want these tasks to return a value to their source thread, but can't figure out how to do that.
I've considered using a future, but there's no way to explicitly set the future's value. I could use a property, but I don't believe those are thread safe.
Every task is an implementation of DBRequest. The actual content varies, but the result of all activities is a string.
An asynchronous thread creates a DBRequest and submits it to the queue. The queue runs the task, which produces a string. How do I get that string back to the thread that created the DBRequest, and how can I cause my creator thread to wait for the result?
public interface DBRequest
String execute(VdtsSysDB vdtsSysDB, BoardLoad currentLoad);
public class DBQueue implements Runnable
private static DBQueue dbQueue;
private LinkedBlockingQueue<DBRequest> queue = new LinkedBlockingQueue<>();
private VdtsSysDB vdtsSysDB = new VdtsSysDB();
private ReentrantLock lock = new ReentrantLock();
private static final Logger LOG = LoggerFactory.getLogger(DBQueue.class);
private boolean kill = false;
private BoardLoad currentLoad;
private ProgressController progressController;
public static DBQueue getInstance()
if (dbQueue == null) synchronized (DBQueue.class)
if (dbQueue == null)
dbQueue = new DBQueue();
return dbQueue;
private DBQueue()
public ReentrantLock getLock()
return lock;
@Override
public void run()
LOG.info("Starting DBQueue loop. Kill .", kill);
while (!kill)
DBRequest dbRequest = removeRequest();
if (dbRequest != null)
lock.lock();
String result = dbRequest.execute(vdtsSysDB, currentLoad);
lock.unlock();
if (progressController != null) Platform.runLater(() ->
progressController.updateDisplay(currentLoad));
vdtsSysDB.getEntityManager().close();
public void addRequest(DBRequest dbRequest)
try
queue.add(dbRequest);
LOG.info("Added request.");
catch (Exception e)
LOG.error("Can't add element.", e);
private DBRequest removeRequest()
DBRequest result = null;
try
//result = queue.poll(10, TimeUnit.SECONDS);
result = queue.take();
catch (Exception e)
LOG.error("Exception.", e);
return result;
public void killDBQueue()
kill = true;
LOG.info("Shutting down DBQueue.");
public static void start()
Thread thread = new Thread(DBQueue.getInstance(), "DBQueue Thread");
thread.start();
LOG.info("Starting DBQueue.");
public BoardLoad getCurrentLoad()
if (currentLoad == null)
currentLoad = BoardLoad.getLastOpenLoad(vdtsSysDB);
return currentLoad;
public void setCurrentLoad(BoardLoad proposedLoad)
// We can only have one open load, and by definition, the current load is open. So close it.
if (this.currentLoad != null && !this.currentLoad.equals(proposedLoad))
currentLoad.close(vdtsSysDB);
if (proposedLoad != null)
this.currentLoad = vdtsSysDB.getEntityManager().find(BoardLoad.class, proposedLoad.getId());
else this.currentLoad = null;
public ProgressController getProgressController()
return progressController;
public void setProgressController(ProgressController progressController)
this.progressController = progressController;
EDIT: I'm using this queue to synchronize database access, reducing the need for locks and ensuring that requests are completed sequentially. I don't believe there is any other way to achieve this sort of asynchronous request -> synchronous request change.
But I'd love to have that belief changed.
java multithreading java-8
java multithreading java-8
edited Nov 13 '18 at 20:57
M. Teasdale
asked Nov 13 '18 at 20:11
M. TeasdaleM. Teasdale
106110
106110
CompletableFutureprovides a way to set a future's value.
– teppic
Nov 13 '18 at 20:27
You might want to run this by codereview. There are quite a few synchronisation problems in your code.
– teppic
Nov 13 '18 at 20:28
1
Your queue sounds likeExecutorServicenot a queue. You can submit tasks toExecutorServicewhich returnsFutureback. So thread that submits task to execute can callFuture.get()to wait for result.
– Ivan
Nov 13 '18 at 20:31
1
@teppic Please do not refer questions with broken code to Code Review. The cross-post is likely to be closed as off-topic.
– 200_success
Nov 13 '18 at 21:28
@200_success. Ah. My apologies. I was unaware of the protocol.
– M. Teasdale
Nov 13 '18 at 21:45
add a comment |
CompletableFutureprovides a way to set a future's value.
– teppic
Nov 13 '18 at 20:27
You might want to run this by codereview. There are quite a few synchronisation problems in your code.
– teppic
Nov 13 '18 at 20:28
1
Your queue sounds likeExecutorServicenot a queue. You can submit tasks toExecutorServicewhich returnsFutureback. So thread that submits task to execute can callFuture.get()to wait for result.
– Ivan
Nov 13 '18 at 20:31
1
@teppic Please do not refer questions with broken code to Code Review. The cross-post is likely to be closed as off-topic.
– 200_success
Nov 13 '18 at 21:28
@200_success. Ah. My apologies. I was unaware of the protocol.
– M. Teasdale
Nov 13 '18 at 21:45
CompletableFuture provides a way to set a future's value.– teppic
Nov 13 '18 at 20:27
CompletableFuture provides a way to set a future's value.– teppic
Nov 13 '18 at 20:27
You might want to run this by codereview. There are quite a few synchronisation problems in your code.
– teppic
Nov 13 '18 at 20:28
You might want to run this by codereview. There are quite a few synchronisation problems in your code.
– teppic
Nov 13 '18 at 20:28
1
1
Your queue sounds like
ExecutorService not a queue. You can submit tasks to ExecutorService which returns Future back. So thread that submits task to execute can call Future.get() to wait for result.– Ivan
Nov 13 '18 at 20:31
Your queue sounds like
ExecutorService not a queue. You can submit tasks to ExecutorService which returns Future back. So thread that submits task to execute can call Future.get() to wait for result.– Ivan
Nov 13 '18 at 20:31
1
1
@teppic Please do not refer questions with broken code to Code Review. The cross-post is likely to be closed as off-topic.
– 200_success
Nov 13 '18 at 21:28
@teppic Please do not refer questions with broken code to Code Review. The cross-post is likely to be closed as off-topic.
– 200_success
Nov 13 '18 at 21:28
@200_success. Ah. My apologies. I was unaware of the protocol.
– M. Teasdale
Nov 13 '18 at 21:45
@200_success. Ah. My apologies. I was unaware of the protocol.
– M. Teasdale
Nov 13 '18 at 21:45
add a comment |
1 Answer
1
active
oldest
votes
You should add a reference to the submitting thread in your DBRequest interface and implement a setResult(String result) (or similar) method to receive the result.
You can implement a CountDownLatch waiting (or similar) on your submitting thread run() method to wait setting latch up when sending request to queue and down in setResult method.
If I'm not clear just let me know and I'll elaborate.
@MyStackRunnethOver thanks for fixing code parts. Still learning SO.
– bfontana
Nov 15 '18 at 21:02
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53288761%2fhow-do-i-get-results-from-my-work-queue-task%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You should add a reference to the submitting thread in your DBRequest interface and implement a setResult(String result) (or similar) method to receive the result.
You can implement a CountDownLatch waiting (or similar) on your submitting thread run() method to wait setting latch up when sending request to queue and down in setResult method.
If I'm not clear just let me know and I'll elaborate.
@MyStackRunnethOver thanks for fixing code parts. Still learning SO.
– bfontana
Nov 15 '18 at 21:02
add a comment |
You should add a reference to the submitting thread in your DBRequest interface and implement a setResult(String result) (or similar) method to receive the result.
You can implement a CountDownLatch waiting (or similar) on your submitting thread run() method to wait setting latch up when sending request to queue and down in setResult method.
If I'm not clear just let me know and I'll elaborate.
@MyStackRunnethOver thanks for fixing code parts. Still learning SO.
– bfontana
Nov 15 '18 at 21:02
add a comment |
You should add a reference to the submitting thread in your DBRequest interface and implement a setResult(String result) (or similar) method to receive the result.
You can implement a CountDownLatch waiting (or similar) on your submitting thread run() method to wait setting latch up when sending request to queue and down in setResult method.
If I'm not clear just let me know and I'll elaborate.
You should add a reference to the submitting thread in your DBRequest interface and implement a setResult(String result) (or similar) method to receive the result.
You can implement a CountDownLatch waiting (or similar) on your submitting thread run() method to wait setting latch up when sending request to queue and down in setResult method.
If I'm not clear just let me know and I'll elaborate.
edited Nov 13 '18 at 21:16
MyStackRunnethOver
782618
782618
answered Nov 13 '18 at 20:37
bfontanabfontana
112
112
@MyStackRunnethOver thanks for fixing code parts. Still learning SO.
– bfontana
Nov 15 '18 at 21:02
add a comment |
@MyStackRunnethOver thanks for fixing code parts. Still learning SO.
– bfontana
Nov 15 '18 at 21:02
@MyStackRunnethOver thanks for fixing code parts. Still learning SO.
– bfontana
Nov 15 '18 at 21:02
@MyStackRunnethOver thanks for fixing code parts. Still learning SO.
– bfontana
Nov 15 '18 at 21:02
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53288761%2fhow-do-i-get-results-from-my-work-queue-task%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
CompletableFutureprovides a way to set a future's value.– teppic
Nov 13 '18 at 20:27
You might want to run this by codereview. There are quite a few synchronisation problems in your code.
– teppic
Nov 13 '18 at 20:28
1
Your queue sounds like
ExecutorServicenot a queue. You can submit tasks toExecutorServicewhich returnsFutureback. So thread that submits task to execute can callFuture.get()to wait for result.– Ivan
Nov 13 '18 at 20:31
1
@teppic Please do not refer questions with broken code to Code Review. The cross-post is likely to be closed as off-topic.
– 200_success
Nov 13 '18 at 21:28
@200_success. Ah. My apologies. I was unaware of the protocol.
– M. Teasdale
Nov 13 '18 at 21:45