Thursday, January 05, 2006

Multi-thread

(1) a thread is terminated
by being interrupted. InterruptedException
run method returns
(2) call to new Threan(runnable).start() to trigger the execution of the thread
(3) to request a thread to terminated, interrupt() method is used
if interrupt() is called on a blocking thread such as sleep or wait,
the blocking thread will be terminated by InterruptedException will thrown
However, the interrupted thread will decide how to react to the InterruptedException. Normally, it is used to terminated the thread
(4) Therefore, thread handling code should check interrupted status

while(!Thread.currentThread().isInterrupted() && hasMoreWork())
{
doMoreWork();
}
However in the loop with sleep() do not need to check isInterrupted()
since interrupt() the blocking thread will throw InterruptedException
(5) Do not ignore InterruptedException
try
{
}catch(InterruptedException e)
{
Thread.currentThread().interrupt();
}

or

void doWork() throws InterruptedException
{
}

(6)Thread state
New new Thread(runnable)
Runnable thread.start() is called
Blocked sleep(), block on I/O, wait for lock, wait for condition, wait()
Dead run() returns or uncaught exception terminate the thread

Please Thread.yield() is a static method. It only yield current executing thread but can not do for specific thread.

To wait for a specific thread to die using thread.join()

Daemon thread is to server other threads. Daemon Thread vs. User Thread

To interrupt many threads in one shot, using ThreadGroup or executors


Two fundamental cocurrent programming issues


race condition

(1) Every Object has implicit lock and implicit condition, synchronize (auto lock/unlock and condition)since object has implicit lock and implicit condition. Thread enters synchronized method auto acquire the lock of the object. However, sychronize only has a single condition

public syncrhonize void doWork() throws InterruptedException
{
while(condition variable)
wait();
execute();
notifyAll(); // every important so that no dead lock
}

(2) A explicit lock, new ReentrantLock() mannual lock(), condition and unlock()
A calling thread can repeatly acquires the lock if it is the owner of the lock
Lock protect the critical section of the code and allow only one thread
executed at a time. Condition Object is used for the thread entering the
protected critical section

objLock.lock(); // if (objLock.tryLock(100, MiliSecond)) so that it quick return
try
{
// both condition test and obj manipulation
// should be in critical section for lock protection
while(!condition variable)
okCondition.await();
doMoreWork();
okCondition.signalAll();
}
finally
{
objLock.unlock();
}
private objLock = new ReenterLock(); // construct the lock for critical section
private Condition okCondition = objLock.newCondition(); // so that it could have many conditions

(3) singalAll() to unblock the waiting threads, Condition Object only
has signalAll(), signal(), await() in order to diff from Object's
wait() and notifyAll()

(4) synchronized block: Java Object diff from Monitor
a. does not have to all private fields
b. methods does not have to all sychronize
c. lock has only one condition

synchronized(obj)
{
critical section
}
private Object obj = new Object();

(5) To make a object field thread safe

a. the field is volatile
b. field is final and it is accessed after constuctor is completed
c. field access is protected by a lock such as synchronize or implicit lock

(6) If there are many reader but less writer

ReentrantReadWriteLock rwl = new ReentrantReadWriteLock ();

public double read()
{
readLock.lock();
try {}
finally { readLock.unlock();}

}

public void write()
{
writeLock.lock();
try{}
finally { writeLock.unlock();}
}




(7)ConcurrentLinkedQueue (non-blocking queue) and ConcurrentHashMap is the most efficient cache and return weakly consistent interators

(8) Copy in Write Array is for large amound of writer to the data structure but
reader read the most latest collection. However the interator is old therefore
the read data may be stale.
(9) Callable task executed asynchronized with return Object, has exeception
Runnable task executed asynchronized no return no exception no paramemters
Future holds the async computation results

Callable computation = ......; // long run task
FutureTask task = new FutureTask(computation);// create future task and use it to start a thread
Thread t = new Thread(task);
t.start();
...........
Integer result = task.get();

(10) for all short live thread using thread pool with Executor.newCachedThreadPool()

ExecutorService pool = Executors.newCachedThreadPool();
Callable computation = .......;// long run task
Future result = pool.submit(computation);

......
pool.shutdown();

ExecutorCompletionService service = new ExecutorCompletionService(executor);
for(Callable task:tasks)
service.submit(task);
for(int i =; i < tasks.size(); i++)
count += service.take().get();
(11) Thread Collaboration (CyclicBarrier, CountDownLatch, Exchanger, SynchronousQueue, Semaphore)

No comments: