ThreadLocal thread of understanding and application scenarios using ThreadLocal thread management of Android

 

ThreadLocal understanding and management of application scenarios Android threads

Preface:

     Recent study concluded Android animation, animation when learned attributes Android's basically looked at the source code inside AnimationHandler access using ThreadLocal, aroused my great curiosity and interest! Access to the relevant information to find that the most important Android Handler message storage mechanism Looper also use ThreadLocal, open source framework EventBus store sends an event queue status under the current thread is using ThreadLocal, ThreadLocal so why use it? ThreadLocal What is it? It can solve any kind of problem? With so many questions to learn under ThreadLocal.

     Thread management Related Articles Address:

ThreadLocal Introduction

   If you simply ThreadLocal literally understand the words like "thread-local" means, in fact, did not mean it, but the name is misleading played too, and it really means is thread-local variables. To see how the official said.

   ThreadLocal definition:  

   Implement a thread-local storage, that is, each thread has its own local variables. All threads share a ThreadLocal objects,

But when each thread to access these variables to get different values, each thread can change these variables and does not affect other threads, and supports null values.

ThreadLocal understand

Each thread sets AnimationHeadler we look at the properties of animation

Copy the code
    private static AnimationHandler getOrCreateAnimationHandler() {
        AnimationHandler handler = sAnimationHandler.get();
        if (handler == null) {
            handler = new AnimationHandler();
            sAnimationHandler.set(handler);
        }
        return handler;
    }
Copy the code

Because protected static ThreadLocal <AnimationHandler> sAnimationHandler = new ThreadLocal <AnimationHandler> (); there is no use of an initialization value, but this is not an object by each new thread is created by copying a variable and out of storage. Many people think that ThreadLocal to solve the problem of multiple threads access shared objects, it is wrong to say that, because whether it is through the initialization of variables or create your own copy of local variables directly through the new, ThreadLocal.set () to the thread object is the thread object for their own use, other threads access is not required, but also access to reach. Each thread is accessed in different objects, change is also its own independent object itself does not belong to the same object, no shared concept, the more impossible to solve the shared object multithreaded access.

Concluded the following from the above understanding

 1. read each thread has its own local variables

     Each thread has a context independent of other threads to save this variable, local variable to other threads of a thread is not visible

 2. Initialize copy is independent of the variable, or initialize a variable of their own

     ThreadLocal can give an initial value, and each thread will receive a copy of the initial value, so as to ensure a different thread has a copy, you can also create a new way for the variable thread

 3. The only variable is changed without disturbing each other between the current thread associated with the thread

    ThreadLocal not solve the problem for the shared variable, thread synchronization in order to coordinate not exist, but in order to facilitate a mechanism to handle their own state of each thread introduced.

So ThreadLocal is neither to solve the problem of access to shared multi-threaded, but not thread synchronization in order to solve the problem, ThreadLocal is designed is to provide a local variable internal thread, easy to read anytime, anywhere in this thread, and isolated from other threads .

ThreadLocal usage scenarios

      At what point was the use of ThreadLocal it? Many times we will create some static field to save the global object, then the object can be accessed any thread, if guaranteed to be thread-safe, but added that nothing issue, but sometimes difficult to ensure security thread, this time we needs are created for each thread's copy of an object, we can also save these objects with ConcurrentMap <thread, object>, that would be more trouble, such as when a thread end how we delete this thread object copies it?

If you are using ThreadLocal do not have this worry, ThreadLocal ensure that each thread has maintained an implicit reference to its copy of a thread-local variables, as long as the thread is alive and the ThreadLocal instance is accessible; after the disappearance of the thread, which thread-local instances All copies will be garbage collection (unless other references to these copies exist of). After checking the data generally get the following two scenarios:

1.) When some of the data in a thread-scoped, and different threads have different copies of the data of the time.

   ThreadLocal occasions mainly to solve the data due to concurrent multi-threading, resulting in inconsistencies. ThreadLocal space for time, provide a copy of the data in concurrent access of each thread to run the business by accessing a copy of this result is consuming memory, but greatly reducing the thread synchronization caused by the thread consumption is reduced the complexity of thread concurrency control.

     Such as Android's Handler message mechanism for Handler, it needs to obtain the current looper thread. Obviously Looper scope is the thread, and different threads have different Looper, this time you can easily access in Looper thread through ThreadLocal.

As another example EventBus, EventBus need to get PostingThreadState object for the current thread, different PostingThreadState the same effect on a different thread,

EventBus can easily get PostingThreadState objects under the current thread, and related operations.

2) the transfer of complex logical object, such as transfer listener

   Use parameter passing, then: When the function call stacks deeper, the design will be very bad, for each thread to define a static variable listener, if it is multi-threaded, then a thread on the need to define a static variable, can not be extended, this time using ThreadLocal you can solve the problem.

 Application Example ThreadLocal

  As a simple example, let each thread has its own unique task queue, similar to the implementation of EventBus.

Copy the code
  private static final ThreadLocal<PriorityQueue<TaskItem>> queueThreadLocal = new ThreadLocal<PriorityQueue<TaskItem>>() {
        @Override
        protected PriorityQueue<TaskItem> initialValue() {
            return new PriorityQueue<>(5);
        }
    };


    public PriorityQueue <TaskItem> getTaskQueue () {
        PriorityQueue <TaskItem> taskItems = queueThreadLocal.get ();
        return taskItems;
    }


    public void addTask (TaskItem taskItem) {
        PriorityQueue <TaskItem> taskItems = queueThreadLocal.get ();
        taskItems.add (taskItem);
    }

    public void removeTask (TaskItem taskItem) {
        PriorityQueue <TaskItem> taskItems = queueThreadLocal.get ();
        if (taskItems.contains (taskItem)) {
            taskItems.remove (taskItem);
        }
    }

    private void exceTask() {
        PriorityQueue <TaskItem> taskItems = queueThreadLocal.get ();
        if (!taskItems.isEmpty()) {
            TaskItem taskItem = taskItems.poll ();
            taskItem.exceTask ();
        }
    }
Copy the code

 Attach TaskItme Code:

Copy the code
public class TaskItem implements Comparable {
    private long Id;
    private String name;
    private int priority;

    public long getId() {
        return Id;
    }

    public void setId(long id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    @Override
    public int compareTo(Object arg0) {
        if (TaskItem.class.isInstance(arg0)) {
            TaskItem tm = (TaskItem) arg0;
            if (tm.priority > priority) {
                return -1;
            } else if (tm.priority < priority) {
                return 1;
            }
        }
        return 0;
    }

    public void exceTask() {
        Log.e("exceTask", "exceTask---id:" + Id + " name:" + name);
    }

}

After the above code can be seen, the task in which thread you are submitted automatically added to the task queue on the inside thread belongs, here in fact by ConcurrentMap <Thread, Object> Save is also possible, she said above relatively trouble.

to sum up:

   If you want to learn by example, then a personal look EventBus recommended for use ThreadLocal example, with a very clever and very easy to understand, just less we use in daily project development ThreadLocal itself, a half will be difficult to find an appropriate scene to get to know it.

 

Preface:

     Recent study concluded Android animation, animation when learned attributes Android's basically looked at the source code inside AnimationHandler access using ThreadLocal, aroused my great curiosity and interest! Access to the relevant information to find that the most important Android Handler message storage mechanism Looper also use ThreadLocal, open source framework EventBus store sends an event queue status under the current thread is using ThreadLocal, ThreadLocal so why use it? ThreadLocal What is it? It can solve any kind of problem? With so many questions to learn under ThreadLocal.

     Thread management Related Articles Address:

ThreadLocal Introduction

   If you simply ThreadLocal literally understand the words like "thread-local" means, in fact, did not mean it, but the name is misleading played too, and it really means is thread-local variables. To see how the official said.

   ThreadLocal definition:  

   Implement a thread-local storage, that is, each thread has its own local variables. All threads share a ThreadLocal objects,

But when each thread to access these variables to get different values, each thread can change these variables and does not affect other threads, and supports null values.

ThreadLocal understand

Each thread sets AnimationHeadler we look at the properties of animation

Copy the code
    private static AnimationHandler getOrCreateAnimationHandler() {
        AnimationHandler handler = sAnimationHandler.get();
        if (handler == null) {
            handler = new AnimationHandler();
            sAnimationHandler.set(handler);
        }
        return handler;
    }
Copy the code

Because protected static ThreadLocal <AnimationHandler> sAnimationHandler = new ThreadLocal <AnimationHandler> (); there is no use of an initialization value, but this is not an object by each new thread is created by copying a variable and out of storage. Many people think that ThreadLocal to solve the problem of multiple threads access shared objects, it is wrong to say that, because whether it is through the initialization of variables or create your own copy of local variables directly through the new, ThreadLocal.set () to the thread object is the thread object for their own use, other threads access is not required, but also access to reach. Each thread is accessed in different objects, change is also its own independent object itself does not belong to the same object, no shared concept, the more impossible to solve the shared object multithreaded access.

Concluded the following from the above understanding

 1. read each thread has its own local variables

     Each thread has a context independent of other threads to save this variable, local variable to other threads of a thread is not visible

 2. Initialize copy is independent of the variable, or initialize a variable of their own

     ThreadLocal can give an initial value, and each thread will receive a copy of the initial value, so as to ensure a different thread has a copy, you can also create a new way for the variable thread

 3. The only variable is changed without disturbing each other between the current thread associated with the thread

    ThreadLocal not solve the problem for the shared variable, thread synchronization in order to coordinate not exist, but in order to facilitate a mechanism to handle their own state of each thread introduced.

So ThreadLocal is neither to solve the problem of access to shared multi-threaded, but not thread synchronization in order to solve the problem, ThreadLocal is designed is to provide a local variable internal thread, easy to read anytime, anywhere in this thread, and isolated from other threads .

ThreadLocal usage scenarios

      At what point was the use of ThreadLocal it? Many times we will create some static field to save the global object, then the object can be accessed any thread, if guaranteed to be thread-safe, but added that nothing issue, but sometimes difficult to ensure security thread, this time we needs are created for each thread's copy of an object, we can also save these objects with ConcurrentMap <thread, object>, that would be more trouble, such as when a thread end how we delete this thread object copies it?

If you are using ThreadLocal do not have this worry, ThreadLocal ensure that each thread has maintained an implicit reference to its copy of a thread-local variables, as long as the thread is alive and the ThreadLocal instance is accessible; after the disappearance of the thread, which thread-local instances All copies will be garbage collection (unless other references to these copies exist of). After checking the data generally get the following two scenarios:

1.) When some of the data in a thread-scoped, and different threads have different copies of the data of the time.

   ThreadLocal occasions mainly to solve the data due to concurrent multi-threading, resulting in inconsistencies. ThreadLocal space for time, provide a copy of the data in concurrent access of each thread to run the business by accessing a copy of this result is consuming memory, but greatly reducing the thread synchronization caused by the thread consumption is reduced the complexity of thread concurrency control.

     Such as Android's Handler message mechanism for Handler, it needs to obtain the current looper thread. Obviously Looper scope is the thread, and different threads have different Looper, this time you can easily access in Looper thread through ThreadLocal.

As another example EventBus, EventBus need to get PostingThreadState object for the current thread, different PostingThreadState the same effect on a different thread,

EventBus can easily get PostingThreadState objects under the current thread, and related operations.

2) the transfer of complex logical object, such as transfer listener

   Use parameter passing, then: When the function call stacks deeper, the design will be very bad, for each thread to define a static variable listener, if it is multi-threaded, then a thread on the need to define a static variable, can not be extended, this time using ThreadLocal you can solve the problem.

 Application Example ThreadLocal

  As a simple example, let each thread has its own unique task queue, similar to the implementation of EventBus.

Copy the code
  private static final ThreadLocal<PriorityQueue<TaskItem>> queueThreadLocal = new ThreadLocal<PriorityQueue<TaskItem>>() {
        @Override
        protected PriorityQueue<TaskItem> initialValue() {
            return new PriorityQueue<>(5);
        }
    };


    public PriorityQueue <TaskItem> getTaskQueue () {
        PriorityQueue <TaskItem> taskItems = queueThreadLocal.get ();
        return taskItems;
    }


    public void addTask (TaskItem taskItem) {
        PriorityQueue <TaskItem> taskItems = queueThreadLocal.get ();
        taskItems.add (taskItem);
    }

    public void removeTask (TaskItem taskItem) {
        PriorityQueue <TaskItem> taskItems = queueThreadLocal.get ();
        if (taskItems.contains (taskItem)) {
            taskItems.remove (taskItem);
        }
    }

    private void exceTask() {
        PriorityQueue <TaskItem> taskItems = queueThreadLocal.get ();
        if (!taskItems.isEmpty()) {
            TaskItem taskItem = taskItems.poll ();
            taskItem.exceTask ();
        }
    }
Copy the code

 Attach TaskItme Code:

Copy the code
public class TaskItem implements Comparable {
    private long Id;
    private String name;
    private int priority;

    public long getId() {
        return Id;
    }

    public void setId(long id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    @Override
    public int compareTo(Object arg0) {
        if (TaskItem.class.isInstance(arg0)) {
            TaskItem tm = (TaskItem) arg0;
            if (tm.priority > priority) {
                return -1;
            } else if (tm.priority < priority) {
                return 1;
            }
        }
        return 0;
    }

    public void exceTask() {
        Log.e("exceTask", "exceTask---id:" + Id + " name:" + name);
    }

}

After the above code can be seen, the task in which thread you are submitted automatically added to the task queue on the inside thread belongs, here in fact by ConcurrentMap <Thread, Object> Save is also possible, she said above relatively trouble.

to sum up:

   If you want to learn by example, then a personal look EventBus recommended for use ThreadLocal example, with a very clever and very easy to understand, just less we use in daily project development ThreadLocal itself, a half will be difficult to find an appropriate scene to get to know it.

 

Guess you like

Origin www.cnblogs.com/awkflf11/p/12616860.html
Recommended