I am writing a multithreaded program and I have a method that has a nested synchronized blocks and I was wondering if I need the inner sync or if just the outer sync is good enough.
public class Tester {
private BlockingQueue<Ticket> q = new LinkedBlockingQueue<>();
private ArrayList<Long> list = new ArrayList<>();
public void acceptTicket(Ticket p) {
try {
synchronized (q) {
q.put(p);
synchronized (list) {
if (list.size() < 5) {
list.add(p.getSize());
} else {
list.remove(0);
list.add(p.getSize());
}
}
}
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
EDIT:
This isn’t a complete class as I am still working on it. But essentially I am trying to emulate a ticket machine. The ticket machine maintains a list of tickets in the BlockingQueue q. Whenever a client adds a ticket to the machine, the machine also keeps track of the price of the last 5 tickets (ArrayList list). So I don’t believe I need the inner sync because its is only this class (the ticket system) that will access the list
The danger with:
Is one day you’ll add a method, or call methods in such an order that in effect it does this as well:
Then it’s just a deadlock timebomb.
Asuming this is the complete class, you can just lock one, or as is common, lock the object itself with
synchronizedon the method. All other access to these privates will need to be synchronized too.Or cleaner:
Cleaner still, but is unlikely to be nessasary in your case (based on what I have seen):