• 并发问题引出ThreadLocal


    ThreadLocal

    Thread-->人类
    Runnable-->任务类

    多线程并发问题引出ThreadLocal
    多线程并发问题的原因:
    操作同一个对象,对对象具有读写权限(只读如拍照,不会改变什么),几乎或者同时操作
    解决这个问题的常规方式:
    同步锁,synchronized代码块。
    我们知道,使用同步锁的时候,程序运行到这个地方就需要等待,成为一个串。十分影响效率。专业人士测试过,效率慢了100多倍
    那么如何解决并发问题呢?
    我们将并发问题的原因分离出来。有些操作是必须并发的,有些操作是因为资源的位置等原因出现并发问题的。只要不会修改原来数据的内容,我们为什么不可以给它一个映像呢?
    当然,绝对的并发就必须牺牲效率。

    ThreadLocal是什么?
    ThreadLocal是一个容器。它有三个方法:
    void set(T value):保存值
    T get():获取值
    void remove():移除值
    ThreadLocal内部其实是一个Map集合。虽然在使用ThreadLocal的时候只使用了值没有给出键,其实它内部使用了当前线程作为键
    Map map=new HashMap<Thread,T>

    package cn.itcast.thread;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.junit.Test;
    
    public class Demo1 {
    
        @Test
        public void fun1(){
            final ThreadLocal<String> t1=new ThreadLocal<String>();
            t1.set("hello");
            System.out.println(t1.get());
            t1.remove();
            System.out.println(t1.get());
        }
        @Test
        public void fun2(){
            final ThreadLocal<String> t1=new ThreadLocal<String>();
            
            new Thread(){
                public void run(){
                    t1.set("内部类");
                    System.out.println(t1.get());
                }
            }.start();
            
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(t1.get());
        }
        @Test
        public void fun3(){
            final Map<Thread,String> map=new HashMap<Thread,String>();
            map.put(Thread.currentThread(), "hello");
            System.out.println(map.get(Thread.currentThread()));
            
            new Thread(){
                public void run(){
                    System.out.println(Thread.currentThread().getName());
                    System.out.println(map.get(Thread.currentThread()));
                }
            }.start();
        }
    }
    
    /**
     * 它内部是一个Map
     */
    class TL<T>{
        private Map<Thread,T> map=new HashMap<Thread,T>();
        
        public void set(T data){
            map.put(Thread.currentThread(),data);
        }
        
        public T get(){
            return map.get(Thread.currentThread());
        }
        
        public void remove(){
            map.remove(Thread.currentThread());
        }
    }
    /**
     * ThreadLocal通常用在一个类的成员上
     * 多个线程访问它时,每个线程都有自己的副本,互不干扰
     * Hibernate中把Session放到了ThreadLocal中!
     */
    class User{
        private ThreadLocal<String> usernameT1=new ThreadLocal<String>();
    }
  • 相关阅读:
    JavaScript系列:JavaScript简介
    Fit自适应布局
    JavaScript数值类型及变量
    表格列Column
    JavaScript系列:ECMAScript引用类型
    Absolute绝对定位
    JavaScript系列:ECMAScript运算符
    JavaScript系列:ECMAScript类型转换
    jQuery Uploadify在ASP.NET MVC3中的使用
    JavaScript系列:ECMAScript语句
  • 原文地址:https://www.cnblogs.com/aigeileshei/p/5715108.html
Copyright © 2020-2023  润新知