关于volatile修饰引用类型的疑惑❓❓❓

线程基础知识

  1. Java数字字面量加下划线
    1. 从java7开始可以为数字加下划线,这些下划线可以让人更易读,Java编译器会去除这些下划线。
  2. 线程的原子性与事务的原子性之间的区别与联系
    1. 前者保证执行中没有别的线程打扰?
    2. 后者保证要么成功,要么失败?
  3. 倒计时门闩和循环栅栏


线程的五种创建方式

  1. start方法启动线程,run方法普通的方法调用!

线程状态与状态之间的迁移

  1. 调用哪些方法,线程会释放锁;调用那些方法,线程不会释放锁?
  2. TimeUnit.SECONDS.sleep(5);为什么有的地方不要try……catch……,而有的地方要呢===>是因为在主线程中不要,而在子线程中要吗???

并发编程之可见性

  1. volatile在保证可见性和顺序性上的实际应用!!!
  1. //线程1:
  2. context = loadContext(); //语句1
  3. inited = true; //语句2
  4. //线程2:
  5. while(!inited ){
  6. sleep()
  7. }
  8. /*doSomethingwithconfig(context);
  9. 前面举这个例子的时候,提到有可能语句2会在语句1之前执行,那么久可能导致context还没被初始化,而线程2中就使用未初始化的context去进行操作,导致程序出错。
  10.   这里如果用volatile关键字对inited变量进行修饰,就不会出现这种问题了,因为当执行到语句2时,必定能保证context已经初始化完毕。*/
  1. 缓存一致性与volatile没有关联?
  2. 没有加volatile依然会进行缓存一致性的操作?
  3. volatile是在jvm虚拟机层面上的,而不是操作系统CPU层面上的???
  4. volatile底层不是由MESI协议实现的!volatile的底层实现原理???

并发编程之原子性

  1. CAS的c语言源码中的汇编指令为什么只有在多核cpu时才要上锁,而单核的时候不用上锁?


synchronized锁深入详解

  1. CAS引发的ABA问题的解决方案:版本号(数值型、boolean型???)、AtomicStampedReference类

多线程与高并发

  1. 父子类的锁===>父子类的实现原理===>子类中有一个指向父类的指针???子类中的m方法synchronized锁的是this,父类中的m方法synchronized锁的也是this
  2. 继承的实现原理(通常所说的两种???)
  3. synchronized可以单独使用,为什么还要和wait和notify搭配使用???
  4. synchronized可以自动释放锁,那么为什么还要notify
  5. wait和notify要一起使用吗???
    1. wait和notify更多的是多线程之间合作完成一项任务===>是一种低级的通信方式
    2. wait是线程阻塞自己,而notify是唤醒别的线程===>必须搭配synchronized一起使用
    3. 每一个对象都有一个与之对应的监视器;每一个监视器里面都有一个该对象的锁和一个等待队列和一个同步队列
    4. wait()方法的语义有两个,一是释放当前对象锁,另一个是进入阻塞队列,可以看到,这些操作都是与监视器相关的,当然要指定一个监视器才能完成这个操作了
    5. synchronized和wait、notify的关系就好比是ReentrantLock和await、signal的关系!
  6. lockInterruptibly方法怎么使用???示例会跑IllegalMonitorStateException异常
  7. 令牌桶
  8. volatile的实现原理?volatile是如何保证可见性和(有序性)禁止指令重排序的?
    1. 缓存一致性协议
    2. 添加内存屏障,各种组合(4种?)在写入和读取之前添加内存屏障,禁止指令重排序
  9. LockSupport的实现相对底层;那么Exchanger是不是用AQS实现的???其他应该都是AQS
    1. Exchanger不是AQS,是LockSupport????
  10. Phaser的原理???
  11. ❓volatile修饰的引用指向的对象中的值发生了改变是观察不到的
    1. ”双缓冲+引用赋值“的方法
    2. 加锁
  12. 多线程程序的调试技巧!!!
  13. 线程缓存的可见性与sleep的关系!!!
  14. 乱码问题的解决—->reload的意思是以某种编码方式去重新打开文件;convert的意思是将目前的编码转换为另一种编码—->要搞清这两者之间的作用、关系,否则在调编码的时候,容易造成越转越乱,最终转不回去了——>比如目前是utf-8,使用了reload以gbk读取,发现乱码,然后只能再reload回utf-8,假如此时convert成utf-8,他的本意是从正确的gbk转换为utf-8,结果他原来就是utf-8但仍以gbk的方式转换为utf-8就会造成编码方式、编码信息的丢失!!!
  15. 有现成的阻塞队列吗?put和take
  16. 为什么用0.75的扩展因子?为什么从8开始变成红黑树?为什么到6又变回到链表?
  17. 回调方法
  18. 钩子方法(callback function)
  19. 回调方法和钩子函数的区别
    1. 钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
    2. 回调函数其实就是调用者把回调函数的函数指针传递给调用函数,当调用函数执行完毕时,通过函数指针来调用回调函数。
  20. 同步队列和等待队列是不同的队列吗???
    1. 同步队列, 首先是获取锁失败,调用park阻塞线程,封装为Node ,然后CAS添加到队列的末尾,然后 在同步队列里面,有头结点的下一个节点被remove掉之后,显式的 调用了 unpark 方法唤醒后继节点去获取锁。这里锁的获取是没有 自旋 的,Node 加入尾部是在CAS循环的。
    2. 等待队列,是已经获取到锁的线程,需要用到其他线程的数据,主动调用 wait() 方法,并且释放锁,唤醒同步队列的后继节点(非公平不用唤醒),然后当前节点构造新的Node进入等待队列,当有其他 在同步队列里面 已经获得锁的线程调用 notify()(或者 signal())之后,才会重新加入同步队列,尝试获取锁。 等待队列的节点也调用了 park () 方法阻塞。
  21. 同步队列、阻塞队列、等待队列、异步队列、条件队列
  22. 阅读AQS的源码+1A2B3C……的面试题!!!
  23. 🌟不断的循环可以放在CAS中,可以放在CAS外面包住CAS,来不断地循环!!!(是两种实现方式)
  24. 内存悬挂???内存泄漏???
  25. 守护线程和用户线程以及其他的一些线程

image.png

  1. null是内存中的一个特殊区域吗?
  2. 让引用等于null,表示引用不指向任何内容了
  3. System.gc();是full gc
  4. 为什么软引用进行gc垃圾回收的时候没有调用finalized方法???
  5. ThreadLocal中有了remove,为什么还要使用弱引用???直接通过remove释放掉key和value不行吗???
  6. 继承一个软引用类型,可以在子类中扩展软引用形成hash表===>ThreadLocal中的ThreadLocalMap中的Entry
  7. 对象在哪里和与该对象相对应的类定义在哪里无关!!!
  8. java中假如ThreadLocalMap的key是强引用类型是会发生内存泄漏的(ThreadLocal已经没用了但是还随着线程一直存在着,占用了不必要的而空间!)
  9. 集合类怎么用iterator迭代器???
  10. lazySet???
  11. 怎么做日志slf4j log4j