Professional Documents
Culture Documents
1. If a thread goes to sleep it does not release the lock. But wait() release the lock.
2. synchronized method(){
system.out.println("heello");
}
is same as :
method(){
synchronized(this){
system.out.println("heello");
}
}
benefit of second approach is that its flexible: This way u can have more then one locks for same
object( if u use some third party object for locking instead of this.) u can sync one method using
obj1 and another method using obj2.
3. http://tutorials.jenkov.com/java-concurrency/thread-pools.html
4.
http://www.deitel.com/articles/java_tutorials/20051126/JavaMultithreading_Tutorial_Part4.html
5. A thread can also wake-up without being notified, interrupted, or times out. This is called
spurious wake-up. Though this will occur rarely, your application must guard against spurious
wake-ups.This can be done by testing a condition which can cause wake-up. If condition is not
true then this wake up is spurious one. So make your thread to wait again.
example:
}
6. Database deadlocks:
If you make sure that all locks are taken in same order by any thread then deadlock can never
occur. eg:
sync(A) sync(B)
sync(B) sync(A)
make sure all thread acquire locks on this order A and then B.
thread1 while waiting on B times out and release lock on A. So thread2 will get lock on A and
complete its execution.
8. BlockingQueue
This is implementation of a normal queue. Just check boundary conditions and put wait and notify.
if boundary condition for an operation is reached then make it wait. And just before you are
adding/removing call notifyAll. Make sure to call notifyAll only when it is actually required.
notifyAll is required only at boundary conditions.
return this.queue.remove(0);
}
Queue queue;
String name;
PoolThread(Queue queue){
this.queue = queue;
}
}
}
pool.execute(taskList);
}
To stop the ThreadPool we can call this.interrupt(); on every thread in thread pool.
10. Java5 Java.util.concurrent package Executor framework is just like thread pool.
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class as
{
public static void main( String[] args )
{
// create and name each runnable
Task task1 = new Task( "task1" );
Task task2 = new Task( "task2" );
Task task3 = new Task( "task3" );
System.out.println( "Starting thread pool" );
This returns a list whose methods are all sync. But dont always rely on this because, it only sync
all methods like add, get etc. individually. All individual operations are thread-safe, but sequences
of operations where the control flow depends on the results of previous operations may be subject
to data races. Other operations like iteration or put-if-absent still require external sync.
synchronized(list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
An example:
// iteration -- contains race conditions
// may require external synchronization
it is possible that at some other location some code is deleting element from list. And if the
timings are bad then that delete operation would execute just after list.size(). In this case,
list.get() is like to return null and doSomething() would potentially throw NPE.
you must lock the entire List while you are iterating by wrapping it with a
synchronized block, synchronizing on the list. This addresses the data race, but
has further costs for concurrency, since locking the entire List while iterating
could block other threads from accessing the list for a long time.
Another example:
Scalability describes how an application's throughput behaves as its workload and available
computing resources increase. A scalable program can handle a proportionally larger workload
with more processors, memory, or I/O bandwidth. Locking a shared resource for exclusive access
is a scalability bottleneck -- it prevents other threads from being able to access that resource,
even if idle processors are available to schedule those threads. To achieve scalability, we must
eliminate or reduce our dependence on exclusive resource locks.
Final Solution:
java.util.concurrent package
However these classes should be used only if required otherwise ArrayList and HashMap are still
widely used.
CopyOnWriteArrayList is used when traversal operation is more than write operations and when
you dont want to sync traversal operation.
Because it stopped the thread without any possibility to save data. You can simulate .stop()
method following ways:
boolean letStop;
void prepareForStop()
void doStop()
in prepareForStop() you can save your data and set letStop variable to true. and if letStop is true
then call doStop().
User threads are service provider threads. When the only threads running are daemon threads
jvm exits. For example garbage collector.
Daemon thread should not be used to run your program. Because consider a scenario: Suppose
you are writing data to a file using daemon thread and if all other threads are done then daemon
thread will also stop and data on file will be left corrupted.
Daemon thread should be used in cases where abrupt termination of thread does not cause any
negative impact.
Think of the JVM as a club. Daemon threads are like the bouncers, and User threads are the
people. Until everyone's gone, the bouncers will stay. But once they leave, the bouncers aren't
needed anymore and they leave too. That's what happens in the JVM. User threads stay until
they're done, and once they're done, the JVM terminates any remaining Daemon threads.
I had a case in which my APP needed to delete some info from my DB each day. I had a thread
like this:
The thing is... when I wanted to stop my APP Server, it hanged, because the Thread was a USER
thread (not daemon) and JVM does not stop until all USER threads finish executing... and my
thread was in a infinite loop!
So, for practical purposes, setting the thread as DAEMON tells the JVM that it has permission to
stop this thread if you are shutting down your app.
run() method for a daemon thread is typically an infinite loop that waits for service requests.
Methods are:
setDaemon(true);
isDaemon();
setDaemon should not be called after .start. If you do then it will throw
java.lang.IllegalThreadStateException
Usually in a non threaded environment main is the last thread to finish.(thats the thread JVM
creates for your program.) But if it is spawning multiple thread even though main thread is over,
other threads keep running.
16. Thread.sleep(xxx )
JVM can guarantee that your thread will not wake up before xxx ms, but it is highly likely that
your thread can sleep more than xxx ms.
endThread(){
stop = true
}
run(){
while(stop!){
/// more code
}
}
18. ThreadLocal :
http://www.javamex.com/tutorials/synchronization_concurrency_thread_local.shtml
When we say :
myTL.set(new Integer(0));// we are basically setting this value in current
// thread's local hashmap. eg. map1.put(myTL, intVal);
---------
http://www.ibm.com/developerworks/java/library/j-threads3.html
Thread-local variables are commonly used to render stateful Singleton or shared objects thread-
safe, either by encapsulating the entire unsafe object in a ThreadLocal or by encapsulating the
object's thread-specific state in a ThreadLocal. For example, in an application that is tightly tied
to a database, many methods may need to access the database. It could be inconvenient to
include a Connection as an argument to every method in the system -- a sloppier, but
significantly more convenient technique would be to access the connection with a Singleton.
However, multiple threads cannot safely share a JDBC Connection. By using a ThreadLocal in
our Singleton, as shown in Listing 3, we can allow any class in our program to easily acquire a
reference to a per-thread Connection. In this way, we can think of a ThreadLocal as allowing us
to create a per-thread-singleton.
-----------------
An example may help clarify this concept. A servlet is executed in a thread, but since many users
may use the same servlet at the same time, many threads will be running the same servlet code
concurrently. If the servlet uses a ThreadLocal object, it can hold data local to each thread. The
user ID is a good example of what could be stored in the ThreadLocal object.
--------------------
http://en.wikipedia.org/wiki/Double-checked_locking
http://www.ibm.com/developerworks/java/library/j-dcl.html
The IBM article is old one. Now from Java 1.5 onwards double check locking works well with
volatile keyword. earlier versions of java did not have correct implementation of volatile keyword
but 1.5 onwards it works. See head first design pattern book for reference.