zoukankan      html  css  js  c++  java
  • ThreadLocal 笔记

    synchronized 同步的机制可以解决多线程并发问题,这种解决方案下,多个线程访问到的都是同一份变量的内容。为了防止在多线程访问的过程中,可能会出现的并发错误。不得不对多个线程的访问进行同步,这样也就意味着,多个线程必须先后对变量的值进行访问或者修改,这是一种以延长访问时间换取线程安全性的策略。

    ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有了自己独立的一个变量,竞争条件被彻底消除了,那就没有任何必要对这些线程进行同步,它们也能最大限度的由CPU调度,并发执行。由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,变量被彻底封闭在每个访问的线程中,并发错误出现的可能也完全消除了。这是一种以空间来换取线程安全性的策略

    ThreadLocal适用于资源共享但不需要维护状态的情况,也就是一个线程对资源的修改,不影响另一个线程的运行。

    ThreadLocal类接口说明:

    • void set(Object value)                            
      • 设置当前线程的线程局部变量的值。
    • public Object get()             
      • 返回当前线程所对应的线程局部变量。
    • protected Object initialValue()          
      • 返回该线程局部变量的初始值,该方法为了让子类覆盖而设计的。
      • 这个方法在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。
      • ThreadLocal中的缺省实现直接返回一个null。
    • public void remove()                       
      • 将当前线程局部变量的值删除,目的是为了加快内存回收的速度,减少内存的占用。

    每个Thread都有自己独立的ThreadLocalMap对象,用来存放各自独立的对象集合。

    在ThreadLocalMap中是以ThreadLocal作为key存储的,所以一个ThreadLocal代表一个隔离变量。

    我们无法直接操纵ThreadLocalMap对象,只能通过ThreadLocal对象用来维护ThreadLocalMap中的变量。

    示意图:

    ThreadLocal示例

    package org.apollo.demo01.demo;
    
    
    public class ThreadLocalDemo {
        
        static class Countor{
            
            ThreadLocal<Integer> threadLocal1=new ThreadLocal<Integer>(){
                protected Integer initialValue() {
                    return 0;
                };
            };
            /**
             * 往ThreadLocalMap中放入Integer用来计数
             */
            public void add(){
                Integer i=threadLocal1.get();
                i++;
                threadLocal1.set(i);
            }
            public void print(){
                Integer i=threadLocal1.get();
                System.out.println(i);
            }
        }
        public static void main(String[] args) {
            
            Runnable runnable=new Runnable() {
                
                Countor countor=new Countor();
                public void run() {
                    for(int i=0;i<10;i++){
                        //多个线程共享countor变量,但不共享计数,计数器会为每个线程单独计数
                        countor.add();
                        countor.print();
                    }
                }
            };
            for(int i=0;i<3;i++){
                Thread t=new Thread(runnable);
                t.start();
            }
            
        }
    }
  • 相关阅读:
    AYIT609暑假集训第一周下训练题题解
    AYIT609暑假集训第一周上训练题题解
    IELTS
    CodeForces451B
    CodeForces1352C
    CodeForces474B
    提供程序-java根据纬度 经度值获取用户的地理位置
    一款java写的将汉字转为拼音的工具类(转)
    MyBatis学习4---使用MyBatis_Generator生成Dto、Dao、Mapping(转)
    MyBatis学习3---使用SqlBuilder生成SQL语句(转)
  • 原文地址:https://www.cnblogs.com/DajiangDev/p/3542543.html
Copyright © 2011-2022 走看看