Java线程锁_模拟失效时修改值
来源:互联网 发布:windows git 配置文件 编辑:程序博客网 时间:2024/06/05 04:48
在开发过程中碰到的一个bug。我有个静态Map用来存储微信的普通access_token,其它接口获取access_token时,会判断access_token是否过期,过期则会调用获取access_token的接口,重新获取access_token,并覆盖Map中的值。
但这里存在并发的情况:在access_token失效时,多个请求同时获取access_token时,就会发生错误,只有最后一次获取的access_token才是可用的,但此时Map里存的却不一定是最后一次获取的access_token。
下面是我模拟过期时,修改值。
静态值
public class StaticProject {public static int count = 0; // 数public static long time = 1505227456849l; // 时间}
失效时调用的方法
public class ChangeValue {public void set(int a) {// 第一层判断if (StaticProject.time < System.currentTimeMillis()) {System.out.println("a = " + a + ", 第1层if, " + StaticProject.count);synchronized(ChangeValue.class) {// 第2层判断if (StaticProject.time < System.currentTimeMillis()) {StaticProject.count = a;StaticProject.time = System.currentTimeMillis() + 7200000;System.out.println("a = " + a + ", 第2层if, " + StaticProject.count);}}System.out.println("a = " + a + ", 第3层, " + StaticProject.count);}}}
线程1
public class Thread1 extends Thread {@Overridepublic void run() {ChangeValue cv = new ChangeValue();cv.set(10);System.out.println("Thread1 = " + StaticProject.count);}}
线程2
public class Thread2 extends Thread {@Overridepublic void run() {ChangeValue cv = new ChangeValue();cv.set(12);System.out.println("Thread2 = " + StaticProject.count);}}
测试
public static void main(String[] args) {Thread1 t1 = new Thread1();Thread2 t2 = new Thread2();t1.start();t2.start();System.out.println("main " + StaticProject.count);}
测试结果1
main 0a = 12, 第1层if, 0a = 10, 第1层if, 0a = 12, 第2层if, 12a = 12, 第3层, 12Thread2 = 12a = 10, 第3层, 12Thread1 = 12
从打印的数据可以看出thread1和thread2调用ChangeValue.set(a)。
均发现时间过期,准备修改时间值。
但thread2先拿到锁,thread2操作后,释放锁。
此时thread1再拿到锁,发现时间已经被修改了,是未过期的时间,则跳过修改。
上面的方案是基于原先的代码,在原先的代码上进行修改的,代码改动量少,但个人觉得不是这个不是好的解决方案。
还有另外的解决方案:专门开启一条线程,用来监视access_token的过期时间,若过期,则重新获取access_token。
这样其它接口可以直接获取access_token,而不用考虑access_token过期的问题。
但这个方案同样有个问题,就是其它接口获取access_token后,同时该监视线程重新获取了access_token,
会导致之前接口获取的access_token失效。
----------上面是个人见解,本人经验有限,如果有不对的地方或者有更好的解决方案,请多多批评指正,谢谢!--------
阅读全文
0 0
- Java线程锁_模拟失效时修改值
- java模拟两个线程锁死
- java模拟线程死锁
- java 模拟线程池
- java 线程死锁模拟
- JAVA模拟线程
- java 线程模拟
- Java基础_线程
- Java笔记_线程
- [Java]_[线程同步]
- Java线程_(二)线程同步与锁
- Java程序模拟QQ空间登录 - 并模拟刷说说的赞(图文) 注意:腾讯修改了加密算法,已失效(2015-01-31)
- eclipse java 源代码修改后运行失效
- Java基础_线程_多线程
- (9)java5的线程【锁lock】与【读写锁_以及模拟缓存(妙用)】技术
- (9)java5的线程【锁lock】与【读写锁_以及模拟缓存(妙用)】技术
- 使用java线程模拟死锁
- java-线程并发-缓冲器-模拟
- [测试]Jmeter-BeanShell的使用介绍
- activeMQ笑脸计划_message cursor
- struct 结构体 、 union 枚举 及 #pragma pack 字节对齐
- leetcode 207. Course Schedule
- Colleciton集合和Map集合的遍历
- Java线程锁_模拟失效时修改值
- android TextView设置中文字体加粗实现方法
- 使用WebSocket与服务器进行通信
- Leetcode OJ 78 Subsets [medium]
- softmax回归
- 字典学习与稀疏表示
- ccf图像旋转
- 各类电阻封装、耐压、功率值
- StringRedisTemplate常用操作,以及如何判断session过期