Reputation: 11
Q1) I created a linked list based implementation of DB Connection Pool. Threads which needs connection poll() it from list and threads release connections using add() or addFirst(). During testing I noticed that even though one thread has locked the list using synchronized(ll) {some code here} , other threads were able to poll() out the connections from the list. This test makes me conclude that only the block of code within {} will be guaranteed to be executed by 1 thread at a time but the object itself i.e. ll , will not get locked and other threads can still write on it. Is that correct ?? then what's the use of putting ll as the monitor ?? I could as well use synchronized(this)..
Q2) If I create the Linked list as thread safe using Collections.synchronizedList() during creation of the List, then can I get rid of the synchronized blocks. Assume I have 2 seperate methods for obtaining connection and releasing connection. Currently both methods uses synchronized blocks to obtain/release connections.
Q3) If I decide to use a non blocking list such as ConcurrentLinkedQueue (we have JDK 1.5) will that help in our case. Our peak connection usage is 30 but we have not imposed any limits in our code, so connections can grow infinitely. We were planning to write a Timer Task which will run in the night and close some connections from the head of the list(old connections), but for executing business logic we would prefer to use connections from tail of the queue since those are latest released connections so that chances of having a non-stale connections are high. But since its a fifo queue so I cannot poll() data from tail of queue, so I am forced to use maybe-stale connections from head of queue. So basically what I need is stack like feature for executing business logic , but queue like feature for implementing timer task. Any data structure which you can suggest.
Upvotes: 0
Views: 186
Reputation: 27190
OK, you have some list:
LinkedList ll = ...;
Synchronizing on ll
does not prevent other threads from accessing the list or modifying the list:
synchronized(ll) {
...protected code...
// This does NOT prevent other threads from examining or updating
// ll while the protected code runs.
}
The only thing that a synchronized
block prevents is, it prevents other threads from synchronizing on the same object at the same time.
The reason for synchronizing some data structure like a linked list is to prevent other threads from seeing the structure in an invalid state when one thread must create that temporary invalid state in order to do its work.
In order to make it work, the block of code that creates the temporary bad state must be synchronized, and every block of code that must be prevented from seeing the bad state must also be synchronized on the same object.
This is useless because no other thread will ever be allowed to synchronize on ll
:
public void run() {
synchronized(ll) {
while(true) {
...
}
}
}
You generally want to keep synchronized
blocks as short as possible: You want the code to get in and get out quickly to minimize the amount of time that other threads will spend waiting for their turn.
Upvotes: 1
Reputation: 310980
Synchronization doesn't lock objects. It locks pieces of code that are synchronizing on the same object. If other pieces of code are using the same object without synchronizing on it, they will proceed.
Upvotes: 0