Summary of Java thread pool interview questions [Internship Check-in 01]

ThreadLocal

Is key null after GC?

uncertain.

(1) When using new ThreadLocal<>().set(s);to define threadlocal, if a variable is not declared on the stack to point to it, then it is only weakly referenced. After gc, the threadlocal will be recycled. If the key is null and the value is still there, it will cause a memory leak. Therefore, be sure to call the remove method after using the threadlocal to avoid memory leaks because the key is null.

(2) When defined using ThreadLocal<object> threadLocal = new ThreadLocal<>();the method, it is equivalent to a variable threadLocal in the stack pointing to this object, forming a strong reference. Even in the entry, as the key, it is a weak reference, but there is always a variable named "threadLocal" in the stack. There is a strong reference pointing to him, so the key will not be empty in this case. But as long as the threadLocal variable disappears after the method in which the variable is located is executed, leaving only a weak reference, the key will still be cleared and become null.

Why does key use weak reference?

If you use strong references, when ThreadLocalthe object's reference (strong reference) is recycled, ThreadLocalMapit still holds ThreadLocalthe strong reference. If the key is not manually deleted, it ThreadLocalwill not be recycled. Therefore, as long as the current thread does not die, ThreadLocalMapthe referenced objects will not be recycled. It will not be recycled, which can be considered to cause Entrya memory leak.

ThreadLocalMap expansion mechanism

At ThreadLocalMap.set()the end of the method, if no data has been cleaned after performing the heuristic cleaning work, and the Entrynumber in the current hash array has reached the expansion threshold of the list (len*2/3), the execution logic will start rehash(): here, the detection cleaning work will be performed first , tablecleaning from the starting position backwards, tablesome data may be cleaned out. At this time, it is decided whether to expand the capacity by keyjudging .nullEntrysize >= threshold * 3/4

Let's take a look at the specific resize()method. For the convenience of demonstration, the expanded tabsize is oldLen * 2, recalculate hashthe position, and then put it into a new tabarray. If hasha conflict occurs, look for the nearest entryslot null. After the traversal is completed, oldTaball the The entrydata has been put into the new one tab.

When used ThreadLocal, the thread copy data created in the parent thread cannot be shared with the child thread in an asynchronous scenario.

In order to solve this problem, there is also a class in the JDK . The implementation principle is that the child thread is created InheritableThreadLocalby calling a method in the parent thread , and the method is called in the constructor. Copy the parent thread data to the child thread in the method .new Thread()Thread#initThreadinit

ThreadLocalPractical use in projects

  1. Store user token
  2. traceId link call

Insert image description here

ThreadPoolExecutor

ThreadPoolExecutor saturation strategy definition

If the number of threads currently running simultaneously reaches the maximum number of threads and the queue is full of tasks, ThreadPoolTaskExecutordefine some strategies:

  • ThreadPoolExecutor.AbortPolicy: (Default) Throw RejectedExecutionExceptionto refuse processing of new tasks.
  • ThreadPoolExecutor.CallerRunsPolicy: Call to execute its own thread to run the task, that is, executerun ( run) the rejected task directly in the thread that called the method. If the executor has been closed, the task will be discarded. Therefore, this strategy will reduce the speed of new task submission and affect the overall performance of the program. You can choose this strategy if your application can tolerate this delay and you require that every task request must be executed.
  • ThreadPoolExecutor.DiscardPolicy: New tasks are not processed and discarded directly.
  • ThreadPoolExecutor.DiscardOldestPolicy: This policy will discard the oldest unprocessed task request.

Two ways to create a thread pool

Method 1: ThreadPoolExecutorCreate via constructor (recommended).

Method 2: Create through Executorthe framework's tool class .Executors

  1. FixedThreadPool:This method returns a thread pool with a fixed number of threads. The number of threads in the thread pool always remains the same. When a new task is submitted, if there are idle threads in the thread pool, it will be executed immediately. If not, the new task will be temporarily stored in a task queue, and when a thread is idle, the task in the task queue will be processed.
  2. SingleThreadExecutor: This method returns a thread pool with only one thread. If more than one task is submitted to the thread pool, the task will be saved in a task queue. When the thread is idle, the tasks in the queue will be executed in first-in, first-out order.
  3. CachedThreadPool: This method returns a thread pool that can adjust the number of threads according to the actual situation. The number of threads in the thread pool is uncertain, but if there are idle threads that can be reused, the reusable threads will be used first. If all threads are working and a new task is submitted, a new thread will be created to handle the task. After all threads complete the execution of the current task, they will be returned to the thread pool for reuse.
  4. ScheduledThreadPool: This returns a thread pool used to run tasks after a given delay or execute tasks periodically.

Method 2 is not recommended because:

FixedThreadPoolAndSingleThreadExecutor : The use is unboundedLinkedBlockingQueue , the maximum length of the task queue is , and a large number of requests may accumulate, resulting in OOM Integer.MAX_VALUE.

CachedThreadPool: A synchronization queue is used SynchronousQueue, which has no capacity. When there are no idle threads, threads are applied for immediately. The number of threads allowed to be created is Integer.MAX_VALUE. A large number of threads may be created, resulting in OOM.

ScheduledThreadPoolAndSingleThreadScheduledExecutor : The unbounded delay blocking queue used DelayedWorkQueuewill automatically expand to 1/2 of the original capacity when the added elements are full, that is, it will never block. The maximum length of the task queue is, and a Integer.MAX_VALUElarge number of requests may accumulate, resulting in OOM.

DelayedWorkQueueThe internal elements are not sorted according to the time they are put in, but the tasks are sorted according to the length of delay. The internal data structure of "heap" is used .

Analysis of thread pool principle

Insert image description here

Runnable vs Callable

RunnableInterfaces don't return results or throw checked exceptions, but Callableinterfaces do.

The tool class Executorscan convert Runnableobjects into Callableobjects, which belongs to the converter pattern.

Differences between submit vs execute

execute()The method is used to submit tasks that do not require a return value, so it is impossible to determine whether the task is successfully executed by the thread pool;

submit()Method is used to submit tasks that require return values. The thread pool will return a FutureTask object Futureof type , and obtain the return value through the method. The method will block the current thread until the task is completed . If the method is used , if the task has not been executed within the time, it will be thrown .Futureget()get()get(long timeout,TimeUnit unit)timeoutjava.util.concurrent.TimeoutException

shutdown() VS shutdownNow()

  • shutdown():Close the thread pool and the status of the thread pool changes to SHUTDOWN. The thread pool no longer accepts new tasks, but the tasks in the queue must be completed .
  • shutdownNow():Close the thread pool and the status of the thread changes STOP. The thread pool will terminate the currently running tasks, stop processing queued tasks and return the List waiting to be executed .

isTerminated() VS isShutdown()

  • isShutDownshutdown()Returns true when the method is called .
  • isTerminatedWhen shutdown()the method is called and all submitted tasks are completed, it returns true

Comparison between ScheduledThreadPoolExecutor and Timer

  • TimerSensitive to changes in system clock, ScheduledThreadPoolExecutornot;
  • TimerThere is only one thread of execution, so long-running tasks can delay other tasks. ScheduledThreadPoolExecutorAny number of threads can be configured. ThreadFactoryFurthermore, you can have full control over the threads created if you want (by providing ;
    . ScheduledThreadPoolExecutorAny number of threads can be configured. ThreadFactoryFurthermore, you can have full control over the threads created if you want (by providing ;
  • TimerTaskA runtime exception thrown in will kill a thread, resulting in a Timerpanic i.e. the scheduled task will no longer run. ScheduledThreadExecutorNot only catches runtime exceptions, but also allows you to handle them if needed (by overriding afterExecutethe method ThreadPoolExecutor). The task that throws the exception will be canceled, but other tasks will continue to run.

Guess you like

Origin blog.csdn.net/m0_63323097/article/details/130590819
Recommended