• 疯狂咸鱼
    2019-09-02
    这是一门神课
    
     9
  • 💪😊
    2019-07-22
    java的垃圾回收使用的是复制算法和标记整理算法,这样对象的内存是变化的吧?那么引用它的栈上的地址也会变掉吗?如果是的话如果hashmap的key如果没有自己实现hashcode的话,是不是就会引起了内存泄漏和程序错乱

    作者回复: 是的,对象的引用也被指向新的地址。

    
     2
  • -W.LI-
    2019-07-20
    老师好!最近正好在看多线程编程指南。有个东西没搞明白。
    我自己写了个demo把所有线程都在临界区调用wait方法,wait方法后是sleep方法。我在主线程调用了notifyall(),在临界区内打印了所有线程的状态,notifyall()之前都是waiting,之后都是blocked。出了临界区之后又打印了一次,发现有一个是timed_waiting,别的还是blocked。
    从表现来看
    notifyall():wait->blocked
    调用notifyall()的线程出临界区释放锁锁:
    竞争到锁定blocked->runnable,别的还是blocked。
    之前老师说notifyall()在出临界区的时候调用比较好,可以防止被唤醒的阻塞状态线程,竞争不到锁再次阻塞。
    notifyall是本地方法看不到实现。我想确认下
    notifyall的逻辑是:唤醒waiting线程->尝试获取锁->获取不到blocked?
    还是:所有waiting状态线程->blocked状态进去锁池队列。(只有在有线程释放锁的时候(出临界区)才会从锁池队列拿一个线程尝试获取锁)。我比较倾向于第二种。没看源码希望老师帮忙解惑下,我特意翻了之前的课在那边也留言了,老师在这回复就好了谢谢老师
    展开

    作者回复: 对的,调用wait之后,会进入到WaitSet队列,当调用notify之后,默认策略是将其从WaitSet队列转至EntryList队列中,再尝试获取锁。

    
     2
  • Nu11PointerEx
    2019-07-31
    刘老师,我有个疑问,文中指出弱引用只能存活再下次GC之前,那假如线程在步骤A设置了threadlocal的值,然后需要在步骤B读出来,但是在AB之间发生了GC,这样会不会导致在步骤B中无法取到对应的值

    作者回复: 如果线程没有销毁,也就是说该key值依然存在引用,即使是弱引用,也不会被回收掉。

    
     1
  • Stalary
    2019-07-28
    老师,ThreadLocal使用的时候我存储了一些请求相关的东西,没有使用remove,但是一次请求结束就会自动释放掉了吧,是不是不会出现内存泄漏?还是没太明白出现内存泄漏的场景,线程不都是工作完就会释放掉了吗

    作者回复: 是的,如果我们的线程在使用ThreadLocal的set之后就立刻销毁了,此时之前set的线程的key值通过垃圾回收回收掉,此时value则会存在内存泄漏,而马上又有下一个线程使用ThreadLocal的set,则会清除之前key为null的value,这种情况下是不会出现内存泄漏的。

    也就是ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。

    我们可以使用set之后,sleep下该线程,等待其他请求都一起使用完了set,这样很容易重现内存中的一部分对象无法回收掉。

     1
     1
  • 明翼
    2019-07-22
    超哥,有问题请教下:
    1)曾经被问到一个问题,就是java多线程分配内存的时候是如何控制并发冲突的那?
    2)能不能结合代码把java内存创建的过程讲一次,比如成员变量的引用是在哪里分配的(我理解是堆上),堆上还是栈上,临时变量那,通过这种整体的讲解会对我们印象比较深刻。
    
     1
  • Jxin
    2019-07-20
    抛砖引玉了,感谢老师的知无不尽。( ´◔‸◔`)
    
     1
  • nightmare
    2019-07-20
    老师cms和g1能不能加餐讲详细一点 因为互联网公司 cms和g1问的非常多

    作者回复: 好的,可以考虑。

    
     1
  • asura
    2020-01-24
    每次看完课程,课后评论也会看完。大家看问题的角度不同,思考纬度也不同,着实学到了很多 👍。感谢老师的热情回答!
    
    
  • ty_young
    2019-10-27
    真的受益颇多,谢谢老师
    
    
  • godtrue
    2019-09-12
    我们的项目中ThreadLocal使用的蛮多的,使用原因是因为接口调用链长不想修改方法生命,但有些参数要透传就用ThreadLocal来透传参数。
    老师能否介绍一下题ThreadLocal的最佳实践?什么场景下会使用?有什么坑需要填?怎么规避风险?

    作者回复: 我们可以读取大部分读写中间件实现源码,可以发现ThreadLocal使用的最为频繁,通常是通过ThreadLocal来获取当前线程的操作类型来实现读写数据源的切换。

    在使用完之后实现remove操作,可以规避风险。

    
    
  • 风轻扬
    2019-09-11
    老师,jdk1.6的substring的内存泄漏问题。除了升级jdk版本,您有没有其他的办法。我在网上搜了一下,没有看到啥好办法

    作者回复: 升级版本就好了,现在基本都是基于1.8版本了

    
    
  • 风轻扬
    2019-09-11
    老师,jdk1.6的substring导致内存泄漏的问题。大字符串截取完之后,我们直接把原大字符串的引用置为null,可以解决这个内存泄漏的问题吗?

    作者回复: 不行,只是原来的引用置为null了,但堆中的字符串对象依然不会被回收掉

    
    
  • Mq
    2019-07-22
    老师threadlocal的entry不回收是因为value吗,另外我不理解jvm怎么知道我这次gc的时候key就可以回收,会不会出现我多次get的时候有一次就取不到了

    作者回复: 如果线程还存活,此时get是能获取到的,因为还存在强引用。如果线程生命周期已经结束,则ThreadLocal的线程本地变量将会失去引用,我们知道ThreadLocal是成员变量,如果key值没有设置为弱引用,则结束生命周期的线程变量依然会存在ThreadLocal中。
    所以,当线程生命周期结束,ThreadLocal的key又为了弱引用,key值就会在垃圾回收期被回收掉。

    
    
我们在线,来聊聊吧