High concurrent programming thread pool papers

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."

Published 18 original articles · won praise 2 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_32285039/article/details/103489316