---补充:见到的代码,都是这样写的呀。
public class Client {
private static class SingletonHolder {
static final Client instance = new Client();
}
public static Client getInstance(){
return SingletonHolder.instance;
}
每次都有这三个,理解了,一句话说一下。刚开始的时候,感觉看这三个货就跟和灰熊打比赛,累呀。
ThreadLocal
参考老王和自己理解。线程要存储自己的变量,有多个,那就是Map,key是"logFd","sqlFd"等等,那你这冲突了呢?用一个地址来存储,我定义一个Object object = new Object这样就不会冲突了,object作为key,这样存储自己的变量,OK。取数据的时候,就根据key拿出自己的对象,每一个线程都是这么想的。
就这么思维转变一下,站在线程之外看线程,理解这个概念。
jdk当然不这么想,定义一个变量作为key,都用这个Key,但是不同线程的Thread的Map是唯一的呀!Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t);JDK提供key,map.set(this, value);就这样,节约了多少的临时变量。效果,就是下面的图。
ThreadLocal表示我JDK定义一个ThreadLocal变量,你要存储什么变量,你调用ThreadLocal.set/get就可以了,还不用类型转换,我会给你存储到你的Map里面,就这么简单。
至于什么内存泄漏,看这些好文章就头疼,key就是这个ThreadLocal变量,更改它找Value,但是可能ThreadLocal被回收了,Value还在,线程池里面调优里面可能会用到。
单例模式
public class signletion {
private static volatile signletion instance;
private signletion(){}; public static signletion getInstance{ if(volatile == null} synchronized(signletion.class){if(volatile == null){signletion = new signletion();}}}return signletion}
强调static,private的构造, dcl-两次检测。美团面试的时候,这都没有写出来。美团还问了:静态方法中不能使用this和supper关键字。成员变量都省略了一个this,可以this吗?加锁。
最佳答案 内部类 58通常,海底捞,机器人,基本都是单例模式。
可以最佳答案:58就跌份了,可以不会不能没有听过呀。
public class signletion(){
private signletion(){}; 私有的构造函数
private static class signletionHolder{ 私有的静态内部类
private static signletion instance = new signletion(); 私有的静态类示例
}
public static signletion getInstance() static函数 返回内部类的实例
{ return signletionholder.instance}
好处:getInstance函数没有锁,用的时候才会初始化,初始化的之后,只会有一个进行初始化。利用了虚拟机的类初始化机制。
HashMap
一句话概述一下,根据key的hashcode,做一次hash运算得到所在的槽位,然后,变量槽位,看这个hash值在吗?因为,不同的key的hashcode可能相同,还要比较,key一样吗?如果都一样,那就更新覆盖,没有那就放在第一个。就这么简单,谁把这个说的这么难?这有什么问题?为什么会死锁,多线程操作的时候,在内存扩展,数据都重新hash的时候,可能形成圆环。
ConcurrentHashMap
1:分段锁,提高并发。
2:增加和删除的时候,都加锁,而且都是COW类型的操作,加锁,保证了正常。
3:get最难理解。volatile保证并发修改的可见性。HashEntry结点都设计final类型,保证删除的时候一致性。
4:count操作的时候,使用乐观锁等。
其实concurrenthashMap是线程安全的,但是,不能完全的保证同步性。
网友评论