static修饰的变量是放在方法区中的,JVM不会回收方法区中的对象,由于hashMap不会被回收,而hashMap中又一直在用着MythreadLocal对象,所以导致MythreadLocal不会被回收
因为Val是引用传递,不是值传递(所以老师才把原来的Integer改成Val<Integer>)。
存的是对象,执行累加时对象的值已经改变了
static修饰的变量是放在方法区中的,JVM不会回收方法区中的对象,由于hashMap不会被回收,而hashMap中又一直在用着MythreadLocal对象,所以导致MythreadLocal不会被回收
可以类比之前提到的++操作,在进行add的时候,可能会出现覆盖问题,毕竟这不是个原子操作
是线程
两个代码块并行啊。
org.springframework:spring-test:5.2.12.RELEASE
jdk11的新特性
你版本比较旧噢, 我是java11
没看懂的啊,就再看一次呀
this 就是这个类本身
HashMap。本身就不是线程安全的,所以 你这个写法 我暂时不确定 是不是能正确的运行
但是既然不是线程安全的 所以 我觉得 不可以这样写
如果你加个锁 确实可以 变成安全的 操作
但是就会 变成多线程 竞争锁 非常消耗性能
虽然实现了 类似功能 但是性能 太低
所以JDK 不会这样设计
小数值取数组是java做的缓存和引用没关系,实际没法用Integer做引用是因为Integer的值是final的,和String一样,创建后没办法改变自身的值,计算后返回的都是一个新的Integer/String
golang 虽然不是线程模型, 但是有协程. 可以把协程理解成其他语言的轻量级线程.
ThreadLocal for golang 无内存泄露, 无竞争,高性能, 不修改golang源码.
支持 go1.18 泛型, 支持 386, amd64, arm, arm64 平台.
支持 go1.13-1.18 版本, 在 linux,windows,mac 上均测试通过.
项目地址 https://github.com/timandy/routine
每个线程中,计算的都是本身进行了add的和。因此,最后把所有的线程中的值取出,求和。就是最后的总和。
因为没重启服务,常量一直保留。
检查引入的包是不是正确。
检查有没有在idea中添加插件
idea中需要设置开启自动开启注解
另外,你的curl read 数据不正确 可能多线程并非造成的,不一定跟@Data注解有关系
因为程序最终是给计算机去执行的。但是,更多的时候,是让开发者能够看懂代码,方便迭代开发。
hello,我用的java 11。 你说的是不是withInitial工厂方法么?
这个HashSet和HashMap的多线程调用时是一样的风险,在扩容时有可能导致死循环,所以要用同步的容器或者同步代码块去调用“添加”的方法
秋田君说的也很不错, 我这里补充下, Map<Thread, T>这种结构,hash表冲突会很严重,举个例子。map.put(thread1, 100);map.put(thread1, 200);map.put(thread1, 300);你发现没有,一个map put了三个值,那取值的时候, 怎么办呢?
锁发生在寄存器里是很快的,锁发生在内存里要看(如果发生在CPU的L1 cache上,就很快),如果发生在L2,L3或者内存里就慢很多;锁如果发生在IO上(比如读硬盘就非常慢)。所以缩小范围,要看缩小了什么,如果缩小了I/O,那就非常有必要了。 我用Sleep(I/O),所谓I/O就是触发中断的东西,来替代真实的I/O场景(比如读数据库,读redis等)。
寄存器速度约等于(l1),< l2, < l3 <<<<< 内存(这里大概有几十倍到百倍速度差距了) <<<<<< 固态硬盘(和内存间有百倍到千倍差距) <<<<<< 机械硬盘(和内存比大概有十万到百万倍差距)。。
initialValue起初始化作用只运行一次,每个Thread对应的Val对象的初始值确实都设为了0,没问题