In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Most people do not understand the knowledge points of this article "what is the use of ThreadLocal?", so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "what is the use of ThreadLocal" article.
1. Common scenes
1. ThreadLocal as a copy of the thread context, then one of the most common ways to use it is to implicitly pass parameters through the two public methods provided, set () and get (), to pass parameters in different methods. For the programming specification, the method definition is limited to the number of parameters, even in some large factories, the number of method parameters is clearly defined.
2, thread safety, each thread maintains its own variables to avoid confusion, such as the commonly used database connection pool thread safety implementation of the use of ThreadLocal.
Second, advanced use
Take parameter passing as an example, how to better use ThreadLocal to realize parameter passing in different methods in the same thread stack. When parameters are passed, there will be parameter names and parameter values, but the get () and set () methods provided by ThreadLocal cannot directly satisfy the setting of parameter names and values. In this case, you need to encapsulate ThreadLocal once. The following code maintains a map object, and then provides setValue (key, value) and getValue (key, value) methods to easily set and obtain parameters; clean up the parameters where needed, and use remove (key) or clear () to achieve.
Import java.util.HashMap;import java.util.Map; public class ThreadLocalManger extends ThreadLocal {private static ThreadLocalManger MANGER = new ThreadLocalManger (); private static HashMap MANGER_MAP = new HashMap (); public static void setValue (String key, Object value) {Map context = MANGER.get () If (context = = null) {synchronized (MANGER_MAP) {if (context = = null) {context = new HashMap (); MANGER.set (context);} context.put (key, value) } public static Object getValue (String key) {Map context = MANGER.get (); if (context! = null) {return context.get (key);} return null;} public static void remove (String key) {Map context = MANGER.get (); if (context! = null) {context.remove (key) }} public static void clear () {Map context = MANGER.get (); if (context! = null) {context.clear ();} III.
Continue to use parameter passing as an example to look at the problems and consequences of using ThreadLocal. In the function development of actual business, in order to improve efficiency, thread pool is used in most cases, such as database connection pool, RPC request connection pool, MQ message processing pool, backend batch job pool, etc.; at the same time, some functions such as heartbeat, monitoring and so on may be realized by using a thread (daemon thread) that accompanies the whole application life cycle. If you use a thread pool, the concurrency must not be low in the actual production business, and the threads in the pool will always be reused; once the daemon thread is created, it will live to the application downtime. So in these cases, the thread life cycle is very long, when using ThreadLocal, be sure to clean up, otherwise there will be a memory overflow. The following case is used to simulate a memory overflow.
Simulate high concurrency scenarios through an endless loop. Create a pool of 10 core threads, 10 maximum threads, 60 seconds idle and thread names starting with ThreadLocal-demo-. In this scenario, 10 threads will run, and the content is simple: generate a UUID, take it as a parameter key, and then set it to the thread copy.
Import org.springframework.scheduling.concurrent.CustomizableThreadFactory;import org.springframework.stereotype.Service; import java.util.UUID;import java.util.concurrent.*; @ Servicepublic class ThreadLocalService {ThreadFactory springThreadFactory = new CustomizableThreadFactory ("TheadLocal-demo-"); ExecutorService executorService = new ThreadPoolExecutor (10,10,60, TimeUnit.SECONDS, new LinkedBlockingQueue (), springThreadFactory); ExecutorService service = new ThreadPoolExecutor (10,10,60, TimeUnit.SECONDS, new LinkedBlockingQueue ()) Public Object setValue () {for (;;) {try {Runnable runnable = new Runnable () {@ Override public void run () {String id = UUID.randomUUID () .toString () / / add ThreadLocalManger.setValue (id, "this is a value"); / / do something here ThreadLocalManger.getValue (id); / / clear () / / ThreadLocalManger.clear () }; executorService.submit (runnable);} catch (Exception e) {e.printStackTrace (); break;}} return "success";}}
The above code has commented out the clear () method, does not clean up, triggers the program, sets the jvm a little lower, and will report the following OOM soon after running.
Java.lang.OutOfMemoryError: GC overhead limit exceededException in thread "TheadLocal-demo-9" Exception in thread TheadLocal-demo-8 "Exception in thread" TheadLocal-demo-6 "Exception in thread" TheadLocal-demo-10 "Exception in thread" TheadLocal-demo-7 "java.lang.OutOfMemoryError: GC overhead limit exceededException in thread" TheadLocal-demo-5 "java.lang.OutOfMemoryError: GC overhead limit exceededjava.lang.OutOfMemoryError: GC overhead limit exceededjava.lang.OutOfMemoryError: GC overhead limit exceeded at com.intellij.rt.debugger.agent.CaptureStorage. InsertEnter (CaptureStorage.java:57) at java.util.concurrent.FutureTask.run (FutureTask.java) at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:624) at java.lang.Thread.run (Thread.java:748) java.lang.OutOfMemoryError: GC overhead limit exceededjava.lang.OutOfMemoryError: GC overhead limit exceeded
A serious memory overflow will occur. As you can see from the screenshot of debug below, the UUID you set up accumulates in memory, gradually increases, and finally bursts the memory.
In the actual business scenario, there may be order number, transaction number, serial number and so on that need to be passed. These variables are often the only ones that do not repeat and conform to the UUID situation in the case. If they are not cleaned up, the application OOM will be made unavailable. In the distributed system, the upstream and downstream systems can also be unavailable, resulting in the unavailability of the whole distributed system. If these information may also be used in network transmission, big messages occupy the network bandwidth, seriously or even lead to network paralysis. So a small detail will put the whole cluster in danger, so how to resolve it reasonably.
IV. Final use
The above problem is to forget the cleanup, so how to make the cleanup unaware, that is, it does not need to clean up and there is no problem. The root is that there is no cleanup after the thread has run once, so a base class thread can be provided to encapsulate the cleanup at the end of the thread execution. The code is as follows. Provides a BaseRunnable abstract base class with the following main features.
1. This class inherits Runnable.
2. Realize two methods: setArg (key, value) and getArg (key).
2. There are two steps in the rewritten run mode. The first step is to call the abstract method task; and the second step is to clean up the thread copy.
With the above three features, inheriting the thread class of BaseRunnable, you only need to implement the task method and the business logic in the task method. Parameter transfer and acquisition can be achieved through setArg (key, value) and getArg (key), without the need to display cleaning.
Public abstract class BaseRunnable implements Runnable {@ Override public void run () {try {task ();} finally {ThreadLocalManger.clear ();}} public void setArg (String key, String value) {ThreadLocalManger.setValue (key, value);} public Object getArg (String key) {return ThreadLocalManger.getValue (key);} public abstract void task () } the above is about the content of this article on "what is the use of ThreadLocal?" I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.