The purpose of using a thread pool
to reduce resource consumption
by reusing threads that have been created to reduce thread creation and destruction caused by the consumption
increase response efficiency
when the mission arrives, the task may not need to wait until the thread creation can be executed immediately
to facilitate the management
thread is a scarce resource, if unlimited creation, not only consumes system resources, but also reduce the stability of the system, using a thread pool can be unified distribution, tuning and monitoring. However, to achieve rational use.
Submit a job to the thread pool thread pool process flow is as follows:
1, to determine the core thread pool threads are all on a mission, if not (core thread is idle or there is no core thread is created) then create a new worker thread to perform the task. If the core threads are on a mission, then enter the next process.
2, the thread pool to determine whether the work queue is full, if the work queue is not full, the task will be stored in the newly submitted job queue. If the work queue is full, then enter the next process.
3, to determine whether the thread pool threads are in working condition, if not, create a new worker thread to perform the task. If full, then to the saturation strategy to deal with this task.
By Executors (JDK1.5 and contract) to create four kinds of ways
to create a cached thread pool newCachedThreadPool, if the length of the thread pool exceeds the processing needs, the flexibility to reclaim idle thread, if not recyclable, the new thread.
newFixedThreadPool create a fixed-size thread pool, you can control the maximum number of concurrent threads, excess threads will wait in the queue.
newScheduledThreadPool create a fixed-size thread pool to support regular and periodic task execution.
schedule (Runable command, long delay, TimeUnit unit): Timing started
scheduleAtFixedRate (Runable command, long initialDelay, long period, TimeUnit unit): after the first timer started, proceed to periodic (cyclic frequency: Last start task execution time as a starting point, and after a period of time, the first task, of course, if the last task execution is not over the next scheduling, even to the period of time it will not perform the next task).
scheduleWithFixedFixedDelay (Runable command, long initialDelay, long delay, TimeUnit unit): after the first timer started, periodic execution continues. (Cycle frequency: After the end of a task, and then after a time delay for the next task scheduling).
newSingleThreadExecutor create a single-threaded, then thread pool, it will only work with a single thread to perform the task to ensure that all tasks are performed in a specified order (FIFO, LIFO, priorities).
In the above method 4 ThreadPoolExecutor underlying implementation is actually four ThreadPoolExecutor constructor.
Executors of the submit method
to submit (Callable task) method opened a thread can get the thread return value, get the current value of the thread returned by get (), when obtaining the return is worth the time if the write operation has not completed this thread will wait ( usually to create a new thread to get the child, so as not to block the main thread). Prior to obtaining the return value of the thread, it will not affect the execution of other threads.
The underlying implementation: future mode (later say)
the shutdown ()
closed the thread pool, violence will not shut down, but will wait for the completion of all tasks performed close. Just send a shutdown signal, shutdown () method after the execution, the thread pool will no longer receive new tasks.
Configuring thread pools
CPU intensive
when the task is executed, does not produce a lot of blocking IO, CPU run faster
configure the maximum number of threads = CPU core number
IO-intensive
the task requires a lot of I / O operations, resulting in blockage, if it is in a single thread execution, you can use multi-threading technology, CPU computing power is not wasted waiting for resources
to configure the maximum number of threads: 2 * CPU core count
the number of CPU usage * CPU * (1 + waiting time / computation time)
the number of CPU through java Runtime.getRuntime (). get availableProcessors () method.
And contracting
stop (deprecated)
Reason: violent terminate the thread, and release the lock held, may cause inconsistent saved data, resulting in data loss and damage permanently
interrupt ()
Interrupts this thread
isInterrupted ()
to determine whether the interrupted
interrupted ()
if it is being interrupted, and clears the current status interrupt
sleep (xx)
blocking (xx milliseconds after re-entering the ready state) will throw an exception due to an interruption, this time, it clears the interrupt flag. So we can interrupt () to set interrupt flags, you can prevent the next cycle can not catch this issue again interrupted in the catch block
lock object .wait ()
thread to wait to release the lock resource
lock object .notify ()
wake the current object lock pool waiting thread
join (x)
so that the target program before execution, and then performs its own after the end of execution (x optional, fill in words is to set long maximum wait more than this duration will return to their continued execution)
essentially make the calling thread wait () and then the current thread object instance
yield ()
to yield the CPU to let others perform, and then re-scramble CUP. (Thread.yeild ())
CountDownLatch
Countdown: new CountDownLatch (x); x represents the number of counts. CountDownLatch, await * (methods, explained after x number of tasks completed before proceeding to
CyclicBarrier
cycle Fence: can counter used repeatedly, when the count task is completed, the next counted once
specific exception class: BrokenBarrierException represent CyclicBarrier has been damaged, no continue to wait for
the semaphore
to allow several threads simultaneously access
the semaphore class
to create objects by new semaphore (x), "x " represents the number of threads allows simultaneous access to
acquire () application semaphore, it will not be obtained until some thread releases the semaphore
acquireUniterruptibly () and acquire () is similar, but does not respond to interrupt
tryAcquire () attempts to obtain a license, failure to return true success returns false, do not wait
release () releases the semaphore
blocking tools: LockSupport
Park (): a hung thread ( similar Suspend ())
to unpark (): restart thread (similar resume ())
Refused strategy: have achieved RejectedExecutionHandler interfaces, if not throw these strategies to meet the application, you can extend yourself RejectedExecutionHandler interfaces (such as rewriting beforeExecute () (before the task starts), afterExecute () (after the end of the mission), terminiated (whole () exit thread pool), etc.)
AbortPolicy
direct throw, that prevent normal work
GallerRumsPolicy
as long as the thread pool is not closed, the policy directly in the caller's thread, run the current task is discarded. Not really discard task, however, the performance of job submission thread is likely to be a sharp decline in
DiscardOledestPolicy
discards the oldest one request, that is a task to be executed, and try to submit the current job again
DiscardPolicy
task can not handle discarded, without any treatment. (Job loss)
must be performed synchronized, the holders of the same lock.
Optimized thread pool
task and submit the number of threads is not one to one relationship. In most cases, a physical thread actually need to handle multiple logical tasks. Therefore, each thread necessarily need to have a task queue. In the actual implementation process, such a situation may occur: A thread has to perform their tasks completed, and thread B and a bunch of tasks waiting for treatment, then thread A will "help" thread B, from queue thread B's to take over a task, which will reach a balance as possible. A notable place is, when a thread tries to help others, always begin to take data from the bottom of the task queue, and when the thread attempts to execute their task is to start from the top of the opposite take. Therefore, this behavior is also very beneficial to avoid data races.
Exception handling, help us to locate the place of throwing an exception:
public class TraceThreadPoolExecutor extends ThreadPoolExecutor{
public TraceThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue){
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
public void execute(Runnable task) {
super.execute(wrap(task, clientTrace(), Thread.currentThread().getName()));
}
@Override
public Future<?> submit(Runnable task) {
return super.submit(wrap(task, clientTrace(), Thread.currentThread().getName()));
}
private Exception clientTrace(){
return new Exception("Client stack trace");
}
private Runnable wrap(final Runnable task, final Exception clientStack, String clientTreadName){
return new Runnable() {
@Override
public void run() {
try{
task.run();
}catch (Exception e){
clientStack.printStackTrace();
throw e;
}
}
};
}
}
threadlocal
to each thread a local variable, but it is not done by threadLocal, but need to come up at the application level to ensure that, if the application is assigned the same object instance for each thread, there is no guarantee ThreadLocal thread safety .
When using ThreadLocal variable maintenance, ThreadLocal provided for each thread using the variable independent variable copy, each thread can independently change their copy without affecting other threads corresponding copy.
4 Method
void SET (Object value)
public Object GET ()
public void Remove ()
protected the initialValue Object ()
Creating threadLocal:
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return 0;
};
};
The bottom is a ThreadLocalMap can be understood as a map collection, key is the current thread
memory leaks
When we use the thread pool, which means the current thread will not necessarily quit. We will set up some objects to a ThreadLocal (it is actually stored within ThreadLocalMap in the thread holding), memory leak problem may cause the system to appear (not run out of clean-up), no longer have to use finished, but it can not be recovered. ThreadLocalMap more similar WeakHashMap, its implementation uses weak references, java virtual machine at the time of garbage collection, if found weak reference, it will immediately recover
Solution: Use ThreadLocal.remove () method to remove the variable, or directly assign null, then the object is more likely to be found in the garbage collector, thus speeding up the recovery. (Eg: t = null, then the corresponding local variables ThreadLocal all threads are likely to be recovered).
Reference books "JAVA high concurrent programming."