1. The state of the thread?
1,New status: new One thread, no more start 2,Running state (ready and running): calling the thread's.start Method 1)Ready to call start Method, CPU No time slice allocated 2)Run, invoked start Method, CPU Scheduling in progress 3,Blocking state: when competing synchronized Lock, not got, thread hangs 4,Waiting state: join,wait,(LockSupport)park Method 5,Timeout wait state: Thread.sleep(long),wait(long),join(long),parkNanos(......) 6,Death status: run The method ends, or run Method throws an exception without
2. Thread pool core parameters
Java provides a way to build thread pools based on Executors
Building directly with Executors results in very coarse thread pool control
Thread pool must be built manually
public ThreadPoolExecutor(int corePoolSize, // Core threads, int maximumPoolSize, // Maximum Thread Lifetime long keepAliveTime, // Lifetime, TimeUnit unit, // Units, BlockingQueue<Runnable> workQueue, //Task Queue, ThreadFactory threadFactory, // Thread factory, to set the name of the thread for later debugging RejectedExecutionHandler handler) {} // Rejection Policy
3. Execution process of thread pool
Submit the task to the thread pool and let the threads in the thread pool execute the task
1. After submitting the task to the thread pool
- If there are idle core threads, execute directly
- If there are no idle core threads, try creating core threads to perform tasks
2. If the core thread count configuration has been reached
Drop the task in the queue and wait for the core thread to finish other tasks before executing me
3. Build a maximum number of threads if the task queue is too full to hold the task
4. Execute rejection policy if the maximum thread is already full
4. What is the use of the ctl attribute in the thread pool?
ctl is a property in the thread pool and is essentially a numeric value of type int
High 3 bits describe the state of the thread pool and low 29 bits describe the number of worker threads
When a thread pool executes a task, it needs to determine the state of the thread pool multiple times to determine whether or not the task needs to be executed (in which way)
Low 29 describes the number of existing worker threads in the thread pool
5. The state of the thread pool?
// RUNNING-Thread Pool is working and can handle submitted tasks!!! private static final int RUNNING = -1 << COUNT_BITS; // Calls the shuwdown() method of the thread pool, from RUNNING -> SHUTDOWN, and does not receive new tasks, but handles existing tasks within the thread pool, including queues private static final int SHUTDOWN = 0 << COUNT_BITS; // Call the shuwdownNow() method of the thread pool, from RUNNING -> STOP, do not receive new tasks, interrupt the task being processed, regardless of the work queue task private static final int STOP = 1 << COUNT_BITS; // Transition state, from SHUTDOWN and STOP P to TIDYING state // SHUTDOWN - Work queue empty, worker thread empty - TIDYING // STOP - Empty worker thread - TIDYING private static final int TIDYING = 2 << COUNT_BITS; // When the thread pool reaches TIDYING, terminated is automatically called in the source code, entering TERMINATED state, and the thread pool is cool private static final int TERMINATED = 3 << COUNT_BITS;
6. What is a worker thread?
In a Java thread pool, a worker thread is a Worker object
The worker threads in the thread pool are represented by the Worker object
addWorker(Runnable, true/false) Add one Worker Object to thread pool, Runnable Specific tasks to be performed true: Core threads added false: Maximum number of threads added Worker This is actually an internal class in the thread pool that inherits AQS,Implemented Runnable private final class Worker extends AbstractQueuedSynchronizer implements Runnable{} The thread pool executes the task, which is actually called Worker In class run Inside Method runWorker Method Worker inherit AQS The purpose is to add an identity to determine if the current worker thread can be interrupted!
7. Where do worker threads reside?
One stored in the thread pool HashSet in private final HashSet<Worker> workers = new HashSet<Worker>();
8. Rejection Policy
1: Abort: Throw an exception public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); } 2: Discard: Throw it away without throwing an exception public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { } 3: DiscardOldest: Throw away tasks that have been queued the longest and are about to be performed public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { e.getQueue().poll(); e.execute(r); // Walk ThreadPool execution process again } } 4: CallerRuns: The caller handles the service, causing a sharp drop in caller performance. public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } }
9. How to do extra processing before and after thread pool execution
try { // Pre-Enhancement beforeExecute(wt, task); try { // Execute Tasks task.run(); } catch (Throwable x) { thrown = x; throw new Error(x); } finally { // Post Enhancement afterExecute(task, thrown); } } protected void beforeExecute(Thread t, Runnable r) { } protected void afterExecute(Runnable r, Throwable t) { }
10. How to Reasonably Allocate Thread Pool Size
When allocating thread pool capacity, you must decide based on your business type CPU Dense, IO Dense, Mixed CPU Dense: More CPU I'm calculating, I've been working IO Dense: More time threads are waiting for a response Mixed: Everything! 1,CPU Dense: less threads, recommended: CPU Number of Kernels+1 2,IO Dense: more threads, recommended: general CPU Number of Kernels * 2,(Thread Wait Time and Threads CPU Time Ratio + 1) * CPU Number 3,Mixed: can CPU Dense and IO Dense operations can be divided into two thread pools to execute!
11. How to ensure thread security if critical (shared) resources exist
1,Mutex: synchronized,Lock(ReentrantLock,ReadWriteLock) 2,Non-blocking lock: CAS(Really unlocked, bottom lock cmpexchg Locked, Java Layer unlocked) 3,No locks are used: ThreadLocal,Use where appropriate volatile Yes! ThreadLocal: Let multiple threads share resources copy Locally, there is no problem with multithreaded operation sharing resources volatile: As long as it doesn't include concurrent operations on shared data, it's basically OK.
12. What exactly is ThreadLocal?
ThreadLocal is essentially a Map.
ThreadLocal binds a data to a local thread.
Thirteen. ThreadLocal memory leak?
Four References in Java
Strong reference: OOM is also not cleared
Soft Reference: Out of Memory Cleanup
Weak references: clear as long as GC
Virtual References: If you can't get a reference, it's cool to build it~~
To solve this problem, remove after using TheadLocal
14. volatile
Visibility and prohibition of instruction rearrangement do not guarantee atomicity!
Why does the CPU reorder instructions?
CPU rearranges instructions to improve efficiency while guaranteeing happens-before
In order to prohibit instruction rearrangement, JVM virtual machine proposed specification, memory barrier
- LoadLoad
- StoreLoad
- LoadStore
- StroeStore
The hotSpot virtual machine is simple to implement by appending a lock between two instructions to specify the effect of implementing volatile
Lock when multithreaded processing shared data at the CPU level.
The lock directive synchronizes data operations in CPU memory to main memory.
15. Pseudo-Sharing (Cache Row Sharing)
CPU is divided into L1, L2, L3 memory, CPU internal memory, which is much faster than looking for data in main memory!
General 64 CPU s have cached rows inside to store data, one of which is 64byte
The usual way to do this is to fill the entire cache row with data from one business.
long l = real data.
long l1,l2,l3,l4,l5,l6,l7;
In JDK1. In 8, the @Contended annotation is usually used
16. CAS
compare And Swap
Problems with CAS:
ABA Problem: Append Version Number Solve
If too many failures take up CPU resources: different scenarios have different solutions
synchronized: The solution is to use an adaptive spin lock and suspend the thread if there are too many spins
LongAdder: When self-increasing, if failed, add failed information to Cell[]
Only one data can be secured: you cannot lock a piece of code like synchronized, ReentrantLock implements the effect of locking based on CAS.
synchronized-ReentrantLock: Watch a video of Teacher Ma and Teacher Huang with systematic explanations
17. ConcurrenthashMap
Just JDK1.8...
ConcurrenthashMap attempts to insert into the array as a CAS when there is no Hash conflict
If there is a Hash conflict, the current array index position is locked back and suspended under the chain table as synchronized
If the length of the array reaches 0.75 of the initial length, double the length of the array and never avoid the inefficiency of queries caused by too long chains
18. How can Concurrent HashMap ensure security during concurrent expansion?
When calculating the hash value of the key in Node, the normal hash value is deliberately defined as a positive number
Negative numbers have a special meaning, if the hash value is -1, it means the current node is expanding
ConcurrenthashMap expands the data table in the old array each time. Size - 1 ~ table. Size - 16 Index position moves before migrating data from other index locations. If a thread inserts data and finds that it is expanding, look for index locations that have not been migrated to help the thread that initially expanded expand.
Initial expansion A:31~16
Thread B inserts data, finds expansion in progress, helps you migrate data, 15~0 index locations
Each migrated data is identified as having been expanded, with a Forwarding Node node placed on it to indicate that the expansion is complete, and then expanded without applying ConcurrentHashMap traversal, queries, and additions (found extensions, will help ~)
19. When a thread expands, it uses sizeCtl to record the number of threads that are expanding now. Why does one thread expand with a low-bit value of 2 and two threads expand with 2?
If sizeCtl is -1, ConcurrentHashMap is initializing and -N is expanding
So you have to identify a thread that is expanding as -2, -2 represents a thread that is expanding
-3 represents two thread extensions.
20. AQS
What is AQS?
AQS is a concurrent base class under JUC package, many of which are implemented based on AQS, such as common ones
ReentrantLock/Semaphore/CountDownLatch/Thread Pool.
AQS structure?
CLH (two-way queue) +state (variable of type int)
Operation state based on bidirectional queues and CAS implements common concurrent content under each JUC
Fair Lock: AQS queues with Node, queue directly without competing for lock resources
Unfair Lock: Nothing, come up and compete directly for lock resources, then go up the routine
This article is published by blog OpenWrite Release!