I’m coding a simple Bank simulator where users would login from different locations at once, using sockets. In the Bank server I keep a bounded buffer to store every incoming request, ex: transfer funds, get account balance etc and there’s a Background Thread running at Server end (Buffer Reader) to pull out each request from this Request Queue (assume it works as a Thread Scheduler in OS), in FCFS basis.
I have made buffer’s put() and get() methods to have conditional synchronization.
ex:
// put method
while(total_buffer_size == current_total_requests) {
System.out.println("Buffer is full");
wait();
}
So my question is, do we have to synchronize methods like get-balance or transfer-funds to avoid corruption of data? I believe it is not necessary since the Buffer Reader takes each request one-by-one and relevant action. Have I avoided any deadlock situations through this? What do you think? Thanks
EDIT2:
public synchronized boolean put(Messenger msg, Thread t, Socket s) throws InterruptedException {
while(total_buffer_size == current_total_requests) {
System.out.println("Buffer is full");
wait();
}
current_total_requests++;
requests[cur_req_in] = new Request(msg, s); // insert into Queue
cur_req_in = (cur_req_in + 1) % total_buffer_size ;
notifyAll();
return true;
}
// take each incoming message in queue. FIFO rule followed
public synchronized Request get() throws InterruptedException {
while(current_total_requests==0) wait();
Request out = requests[cur_req_out];
requests[cur_req_out] = null;
cur_req_out = (cur_req_out + 1) % total_buffer_size ;
current_total_requests--;
notifyAll(); //wake all waiting threads to continue put()
return out;
}
If there is only one consumer (i.e. one thread that consumes the requests from the “buffer”) , then you don’t need to use any synchronization on the methods relating to the bank account. However, I don’t believe that your current implementation of a “bounded buffer” is valid. To be more specific:
There is absolutely no guarantee how many threads will get past the while loop, perform a context switch just before
current_total_requestsis incremented and queue more requests than what’s allowed the buffer size. Unless yourputmethod is synchronized, this approach will be extremely unreliable and prone to race conditions.If you want a bounded buffer, then just use one of Java’s already existing “bounded buffers” or more specifically: the BlockingQueue. The
BlockingQueueblocks onput(...):It also blocks on
take()if there is no data in the queue. I don’t know if you can use one of the items in the concurrency library, but if you can’t then you have to fix yourBoundedBuffer.