知识点捡漏

1.ThreadLocal的数据结构,为什么要用static final 修饰ThreadLocal?

ThreadLocal结构
某个threadlocal在全局是唯一的,并且存取的时候threadlocal只是作为Threadlocalmap下的一个key,所以用static final修饰可以避免发生资源浪费
    1、每个Thread对象内部都维护了一个ThreadLocalMap这样一个ThreadLocal的Map,可以存放若干个ThreadLocal。

/* ThreadLocal values pertaining to this thread. This map is maintained
 * by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
    2、当我们在调用get()方法的时候,先获取当前线程,然后获取到当前线程的ThreadLocalMap对象,如果非空,那么取出ThreadLocal的value,否则进行初始化,初始化就是将initialValue的值set到ThreadLocal中。


public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null)
            return (T)e.value;
    }
    return setInitialValue();
}

 
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
  3、当我们调用set()方法的时候,很常规,就是将值设置进ThreadLocal中。

  4、总结:当我们调用get方法的时候,其实每个当前线程中都有一个ThreadLocal。每次获取或者设置都是对该ThreadLocal进行的操作,是与其他线程分开的。

  5、应用场景:当很多线程需要多次使用同一个对象,并且需要该对象具有相同初始化值的时候最适合使用ThreadLocal。

  6、其实说再多也不如看一下源码来得清晰。如果要看源码,其中涉及到一个WeakReference和一个Map,这两个地方需要了解下,这两个东西分别是a.Java的弱引用,也就是GC的时候会销毁该引用所包裹(引用)的对象,这个threadLocal作为key可能被销毁,但是只要我们定义成他的类不卸载,tl这个强引用就始终引用着这个ThreadLocal的,永远不会被gc掉。b.和HashMap差不多。

  事实上,从本质来讲,就是每个线程都维护了一个map,而这个map的key就是threadLocal,而值就是我们set的那个值,每次线程在get的时候,都从自己的变量中取值,既然从自己的变量中取值,那肯定就不存在线程安全问题,总体来讲,ThreadLocal这个变量的状态根本没有发生变化,他仅仅是充当一个key的角色,另外提供给每一个线程一个初始值。如果允许的话,我们自己就能实现一个这样的功能,只不过恰好JDK就已经帮我们做了这个事情。

2.重写equals为什么要重写hashCode()?

首先,从Object的源码入手:
/**
     * The {@code equals} method for class {@code Object} implements
     * the most discriminating possible equivalence relation on objects;
     * that is, for any non-null reference values {@code x} and
     * {@code y}, this method returns {@code true} if and only
     * if {@code x} and {@code y} refer to the same object
     * ({@code x == y} has the value {@code true}).
     * <p>
     * Note that it is generally necessary to override the {@code hashCode}
     * method whenever this method is overridden, so as to maintain the
     * general contract for the {@code hashCode} method, which states
     * that equal objects must have equal hash codes.
**/
 public boolean equals(Object obj) {
        //equals默认比较的是句柄的内存引用地址
        return (this == obj);
 }

  /**
  * hashcode方法是一个native方法,默认返回引用地址
  **/
  public native int hashCode();

根据源码注释不难发现,equals必须遵从对等原则,x.equals(y) ==true 则
y.equals(x)==true,同时若复写equals,则不需复写hashcode。原因是:
若x.equals(y) ==true,则x.hashcode() == y.hashcode();

可以说这是一种原则上的规范;

一致性哈希

一致性hash传送门

java线程状态切换

java线程状态切换

synchronized 和 Lock 区别

传送门

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 面试必背 会舍弃、总结概括——根据我这些年面试和看面试题搜集过来的知识点汇总而来 建议根据我的写的面试应对思路中的...
    luoyangzk阅读 6,858评论 6 173
  • Overriding the equals method seems simple, but there are ...
    MrDcheng阅读 756评论 0 0
  • 人生如梦,其实无关对错。 毕竟就梦一场,每个人都一样,沉睡地多长梦就多长。富翁与乞丐都是同一样的时间,其实都只是追...
    meet_again阅读 200评论 0 0
  • 今天读了《人本教练》激情篇。让我感触颇深一个人一定要活出激情。活出自我的价值!引用书中的一句话,没有激情的人就像一...
    Sky云霄阅读 469评论 0 0
  • 那是系着牵挂常常的线 缝的是我最爱的那一件 就在窗下那盏昏黄的灯前 妈妈一针针仔细地连 不论是在眼前还是天边 我也...
    由来已久yang阅读 256评论 0 0