Synchronizing queue problems? [on hold]











up vote
-2
down vote

favorite












I've been told that the following code has numerous synchronization problems, but I don't have sufficient experience with multithreading to identify and resolve them. Any feedback would be great.



I have a number of asynchronous threads that want to access a database for reads and writes. The rate of collisions is very high, and there are numerous instances where one thread's operation depends on the completion of another thread's operation, so I implemented a thread with a queue to synchronize these accesses.



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









share|improve this question







New contributor




M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











put on hold as off-topic by 200_success, πάντα ῥεῖ, Edward, Quill, Jamal 2 days ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – 200_success, πάντα ῥεῖ, Edward, Quill, Jamal

If this question can be reworded to fit the rules in the help center, please edit the question.









  • 1




    Welcome to Code Review. Your code must be working correctly, to the best of your knowledge, before we can review it. If you are already aware that it has synchronization problems, and are asking questions like "How can I cause my creator thread to wait for the result?", then your question is off-topic for Code Review. See the help center.
    – 200_success
    2 days ago










  • Understood. Thanks.
    – M. Teasdale
    2 days ago















up vote
-2
down vote

favorite












I've been told that the following code has numerous synchronization problems, but I don't have sufficient experience with multithreading to identify and resolve them. Any feedback would be great.



I have a number of asynchronous threads that want to access a database for reads and writes. The rate of collisions is very high, and there are numerous instances where one thread's operation depends on the completion of another thread's operation, so I implemented a thread with a queue to synchronize these accesses.



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









share|improve this question







New contributor




M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











put on hold as off-topic by 200_success, πάντα ῥεῖ, Edward, Quill, Jamal 2 days ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – 200_success, πάντα ῥεῖ, Edward, Quill, Jamal

If this question can be reworded to fit the rules in the help center, please edit the question.









  • 1




    Welcome to Code Review. Your code must be working correctly, to the best of your knowledge, before we can review it. If you are already aware that it has synchronization problems, and are asking questions like "How can I cause my creator thread to wait for the result?", then your question is off-topic for Code Review. See the help center.
    – 200_success
    2 days ago










  • Understood. Thanks.
    – M. Teasdale
    2 days ago













up vote
-2
down vote

favorite









up vote
-2
down vote

favorite











I've been told that the following code has numerous synchronization problems, but I don't have sufficient experience with multithreading to identify and resolve them. Any feedback would be great.



I have a number of asynchronous threads that want to access a database for reads and writes. The rate of collisions is very high, and there are numerous instances where one thread's operation depends on the completion of another thread's operation, so I implemented a thread with a queue to synchronize these accesses.



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









share|improve this question







New contributor




M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I've been told that the following code has numerous synchronization problems, but I don't have sufficient experience with multithreading to identify and resolve them. Any feedback would be great.



I have a number of asynchronous threads that want to access a database for reads and writes. The rate of collisions is very high, and there are numerous instances where one thread's operation depends on the completion of another thread's operation, so I implemented a thread with a queue to synchronize these accesses.



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






java multithreading queue






share|improve this question







New contributor




M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 days ago









M. Teasdale

11




11




New contributor




M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






M. Teasdale is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




put on hold as off-topic by 200_success, πάντα ῥεῖ, Edward, Quill, Jamal 2 days ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – 200_success, πάντα ῥεῖ, Edward, Quill, Jamal

If this question can be reworded to fit the rules in the help center, please edit the question.




put on hold as off-topic by 200_success, πάντα ῥεῖ, Edward, Quill, Jamal 2 days ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – 200_success, πάντα ῥεῖ, Edward, Quill, Jamal

If this question can be reworded to fit the rules in the help center, please edit the question.








  • 1




    Welcome to Code Review. Your code must be working correctly, to the best of your knowledge, before we can review it. If you are already aware that it has synchronization problems, and are asking questions like "How can I cause my creator thread to wait for the result?", then your question is off-topic for Code Review. See the help center.
    – 200_success
    2 days ago










  • Understood. Thanks.
    – M. Teasdale
    2 days ago














  • 1




    Welcome to Code Review. Your code must be working correctly, to the best of your knowledge, before we can review it. If you are already aware that it has synchronization problems, and are asking questions like "How can I cause my creator thread to wait for the result?", then your question is off-topic for Code Review. See the help center.
    – 200_success
    2 days ago










  • Understood. Thanks.
    – M. Teasdale
    2 days ago








1




1




Welcome to Code Review. Your code must be working correctly, to the best of your knowledge, before we can review it. If you are already aware that it has synchronization problems, and are asking questions like "How can I cause my creator thread to wait for the result?", then your question is off-topic for Code Review. See the help center.
– 200_success
2 days ago




Welcome to Code Review. Your code must be working correctly, to the best of your knowledge, before we can review it. If you are already aware that it has synchronization problems, and are asking questions like "How can I cause my creator thread to wait for the result?", then your question is off-topic for Code Review. See the help center.
– 200_success
2 days ago












Understood. Thanks.
– M. Teasdale
2 days ago




Understood. Thanks.
– M. Teasdale
2 days ago















active

oldest

votes






















active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes

Popular posts from this blog

Morgemoulin

Scott Moir

Souastre