Threadlocal Understanding and application scenario of Android Threading Management (v)

Source: Internet
Author: User
Tags eventbus

Objective:

Recently in learning to summarize the animation effect of Android, when learning about the Android properties animation when the source code, the inside of the Animationhandler access to use the threadlocal, aroused my great curiosity and interest! Check out the information found Android most important handler message mechanism inside the Looper storage is also the use of threadlocal, open source Framework Eventbus store the current thread of the sending event queue status is also the use of threadlocal, So why use threadlocal? What is threadlocal? What kind of problems can it solve? To learn the threadlocal with such doubt.

Threadlocal Introduction

Threadlocal if the literal understanding of the words seems to be "local thread" meaning, in fact, this is not the meaning, but the name is too easy to misunderstand, it really means the thread local variables. Let's see what the authorities say.

/** * Implements A thread-local storage, that's, a variable for which each thread * have its own value. All threads share the same {@code ThreadLocal} object, * But each sees a different value when accessing it, and changes Ma De by one * thread does not affect the other threads. The implementation supports * {@code null} values. * * @see Java.lang.Thread * @author Bob Lee * *

haha as learning slag English is not good, with the help of Baidu translated a bit. I don't know if it's right.

Implement a thread-local storage, that is, each thread has its own local variable. All threads share a Threadlocal object, but each thread can get different values when accessing these variables, each of which can change these variables without affecting other threads and supports null values.

Threadlocal Understanding

Let's take a look at the property animation to set Animationheadler for each thread

    Private Static Animationhandler Getorcreateanimationhandler () {        = sanimationhandler.get ();         if NULL ) {            new  Animationhandler ();            Sanimationhandler.set (handler);        }         return handler;    }

Because protected static threadlocal<animationhandler> Sanimationhandler =new threadlocal<animationhandler> () There is no initialization value here, but instead of a copy of a variable, each thread creates an object from new and then saves it. Many people think that ThreadLocal is to solve the multi-threaded access problem of shared objects, which is wrong, because either by initializing a copy of a variable or by creating its own local variable directly from new, Threadlocal.set () Objects in the thread are objects that the thread uses for itself, and other threads do not need access or access. Each thread accesses a different object, changes its own independent object, itself does not belong to the same object, there is no concept of sharing, it is more impossible to solve the multi-threaded access to the shared object.

Summarize the following points through the above comprehension

1. Each thread reads its own local variables

Each thread has a context that is separate from the other threads to hold the variable, and the local variables of one thread are not visible to other threads

2. Independent of the initialization copy of the variable, or initialize a variable that belongs to itself

Threadlocal can give an initial value, and each thread will get a copy of the initialization value to ensure that different threads have a copy, as well as a new way to create a variable for the thread

3. Variable changes are only associated with the current thread, and the threads do not interfere with each other

ThreadLocal is not intended to solve the problem of shared variables, not to reconcile thread synchronization but to introduce a mechanism to facilitate each thread's handling of its own state.

So threadlocal is not to solve the problem of shared multi-threaded access, and not to solve the thread synchronization problem, threadlocal is designed to provide local variables inside the thread, easy to read anywhere in this thread, and isolated from other threads.

Threadlocal Usage Scenarios

When we say so many concepts, in the final analysis, when do we use threadlocal? Many times we create some static domain to hold the global object, then this object can be accessed by any thread, if it is guaranteed to be thread-safe, that is not a problem, but sometimes it is difficult to ensure thread safety, at this time we need to create a copy of the object for each thread, We can also use Concurrentmap<thread, object> to save these objects, which will be more troublesome, such as when a thread ends, how do we delete the object copy of this thread? If you don't have to worry about using ThreadLocal, ThreadLocal guarantees that each thread keeps an implicit reference to the copy of its thread's local variables, as long as the thread is active and the ThreadLocal instance is accessible; All copies of its thread-local instances are garbage collected (unless there are other references to those replicas). The following two scenarios are generally available through the access information:

1.) When some data is scoped to a thread, and different threads have different copies of the data.

Threadlocal is mainly used to solve the problem that data in multi-threading is inconsistent with concurrency. Threadlocal provides a copy of the data for concurrent access in each thread with space-time, and runs the business by accessing the replica, which consumes memory, but greatly reduces the thread consumption caused by thread synchronization and reduces the complexity of thread concurrency control.

For example, Android's handler message mechanism, for handler, it needs to get the looper of the current thread is obviously looper scope is the thread and different threads have different looper, This time, access to the Looper thread can be easily achieved through threadlocal. Again, for example, the open source framework Eventbus,eventbus needs to get the Postingthreadstate object of the current thread, and different postingthreadstate work on different threads. Eventbus can easily get the Postingthreadstate object under the current thread and then do the related operations.

2.) Complex logic for object delivery, such as listener delivery

Use parameters to pass: When the function call stack is deeper, the design will be very bad, for each thread to define a static variable listener, if it is multi-threaded, a thread needs to define a static variable, cannot be extended, this time using threadlocal can solve the problem.

Threadlocal Use Example

To give a simple example, let each thread have its own unique task queue, similar to the implementation of Eventbus.

  Private Static FinalThreadlocal<priorityqueue<taskitem>> queuethreadlocal =NewThreadlocal<priorityqueue<taskitem>>() {@OverrideprotectedPriorityqueue<taskitem>InitialValue () {return NewPriorityqueue<> (5);    }    };  PublicPriorityqueue<taskitem>Gettaskqueue () {Priorityqueue<TaskItem> TaskItems =Queuethreadlocal.get (); returnTaskItems; }     Public voidAddTask (TaskItem TaskItem) {priorityqueue<TaskItem> TaskItems =Queuethreadlocal.get ();    Taskitems.add (TaskItem); }     Public voidRemovetask (TaskItem TaskItem) {priorityqueue<TaskItem> TaskItems =Queuethreadlocal.get (); if(Taskitems.contains (TaskItem)) {taskitems.remove (TaskItem); }    }    Private voidExcetask () {Priorityqueue<TaskItem> TaskItems =Queuethreadlocal.get (); if(!Taskitems.isempty ()) {TaskItem TaskItem=Taskitems.poll ();        Taskitem.excetask (); }    }

Attach the Taskitme code:

 Public classTaskItemImplementsComparable {Private LongId; PrivateString name; Private intPriority ;  Public LonggetId () {returnId; }     Public voidSetId (LongID) {ID=ID; }     PublicString GetName () {returnname; }     Public voidsetName (String name) { This. Name =name; }     Public intgetpriority () {returnPriority ; }     Public voidSetPriority (intPriority ) {         This. Priority =Priority ; } @Override Public intcompareTo (Object arg0) {if(TaskItem.class. Isinstance (arg0)) {TaskItem TM=(TaskItem) arg0; if(Tm.priority >Priority ) {                return-1; } Else if(Tm.priority <Priority ) {                return1; }        }        return0; }     Public voidExcetask () {LOG.E ("Excetask", "Excetask---ID:" + ID + "Name:" +name); }}

Through the above code can be seen, you are in which thread submitted task naturally added to the thread belongs to the task queue, here in fact through the Concurrentmap<thread, object> preservation is also possible, the above also said relatively troublesome.

Summarize:

Because the understanding of threadlocal is not very deep, just understand a little bit, perhaps some of the views may not be correct, I hope to see the friend criticized the thank you. If you want to learn through an example, personal advice to look at the use of the threadlocal paradigm in Eventbus, with a very clever and easy to understand, but threadlocal itself we use in the daily project development of relatively few, It's hard to find the right scene to understand it in a half-time.

Threadlocal Understanding and application scenario of Android Threading Management (v)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.