How do I get results from my work queue task?










0















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.










share|improve this question
























  • 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






  • 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






  • 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















0















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.










share|improve this question
























  • 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






  • 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






  • 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













0












0








0








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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 20:57







M. Teasdale

















asked Nov 13 '18 at 20:11









M. TeasdaleM. Teasdale

106110




106110












  • 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






  • 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






  • 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











  • 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 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





    @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












1 Answer
1






active

oldest

votes


















1














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.






share|improve this answer

























  • @MyStackRunnethOver thanks for fixing code parts. Still learning SO.

    – bfontana
    Nov 15 '18 at 21:02










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
);



);













draft saved

draft discarded


















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









1














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.






share|improve this answer

























  • @MyStackRunnethOver thanks for fixing code parts. Still learning SO.

    – bfontana
    Nov 15 '18 at 21:02















1














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.






share|improve this answer

























  • @MyStackRunnethOver thanks for fixing code parts. Still learning SO.

    – bfontana
    Nov 15 '18 at 21:02













1












1








1







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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

















  • @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

















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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







這個網誌中的熱門文章

What does pagestruct do in Eviews?

Dutch intervention in Lombok and Karangasem

Channel Islands