concurrent工具类
concurrent 工具类
#CountDownLatch
阻塞直到数完为止
比如说下班锁门,必须要等屋子里所有人都走了之后,才能锁门。
1 | package xyz.onns.juc; |
1 | $ /Library/Java/JavaVirtualMachines/jdk-13.0.2.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=57648:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/onns/Documents/code/java/jvm/out/production/jvm xyz.onns.juc.CountDownLatchTest |
假如上面的i
变成10
,第十个人是否会“被锁在里面”是不固定的。
#CyclicBarrier
等待前置条件全部满足之后,才会执行后面的操作
必须要集齐七颗龙珠
,才能召唤神龙 🐲。
1 | package xyz.onns.juc; |
这样写,第十三行会报错:
Variable used in lambda expression should be final or effectively final
查了一下,首先,这样做的原因是,因为 Java 是这样规定的:Lambda Expressions
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.
至于为什么会这样规定,参照这里:Why are only final variables accessible in anonymous class?
When you create an instance of an anonymous inner class, any variables which are used within that class have their values copied in via the autogenerated constructor. This avoids the compiler having to autogenerate various extra types to hold the logical state of the “local variables”, as for example the C# compiler does… (When C# captures a variable in an anonymous function, it really captures the variable - the closure can update the variable in a way which is seen by the main body of the method, and vice versa.)
As the value has been copied into the instance of the anonymous inner class, it would look odd if the variable could be modified by the rest of the method - you could have code which appeared to be working with an out-of-date variable (because that’s effectively what would be happening… you’d be working with a copy taken at a different time). Likewise if you could make changes within the anonymous inner class, developers might expect those changes to be visible within the body of the enclosing method.
Making the variable final removes all these possibilities - as the value can’t be changed at all, you don’t need to worry about whether such changes will be visible. The only ways to allow the method and the anonymous inner class see each other’s changes is to use a mutable type of some description. This could be the enclosing class itself, an array, a mutable wrapper type… anything like that. Basically it’s a bit like communicating between one method and another: changes made to the parameters of one method aren’t seen by its caller, but changes made to the objects referred to by the parameters are seen.
简单来说,实现可修改的变量功能所带来便利,没有随之而来的问题多。
解决办法就是,加一个final
变量,其实从Java 1.8
之后,你不加final
关键字,只要这个值没被修改,也会默认视作final
的。
1 | package xyz.onns.juc; |
1 | $ /Library/Java/JavaVirtualMachines/jdk-13.0.2.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=57758:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/onns/Documents/code/java/jvm/out/production/jvm xyz.onns.juc.CyclicBarrierTest |
#相关链接
- Variable used in lambda expression should be final or effectively final
- 编译器说 Lambda 表达式中的变量必须是 final 的,我偏不信
- Why does variables in lambdas have to be final or effectively final? [duplicate]
- Lambdas: local variables need final, instance variables don’t
- Why are only final variables accessible in anonymous class?
#Semaphore
信号量
抢车位,有空车位才能停车
1 | package xyz.onns.juc; |
1 | $ /Library/Java/JavaVirtualMachines/jdk-13.0.2.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=58074:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/onns/Documents/code/java/jvm/out/production/jvm xyz.onns.juc.SemaphoreTest |
在教程的基础上改变了些,发现出 bug 了= =
找了半个多小时,解决了!
释放车位输出到控制台,不应该在在释放之后,这样可能会,释放了但是来不及打印,那边线程就已经拿到车位了。
释放车位
-> 获得车位
-> 打印输出
释放车位
-> 打印输出
-> 获得车位
第一步之后,另外的两步是没有办法保证顺序的!所以改为:
打印输出
-> 释放车位
-> 获得车位
1 | package xyz.onns.juc; |
1 | $ /Library/Java/JavaVirtualMachines/jdk-13.0.2.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=58503:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/onns/Documents/code/java/jvm/out/production/jvm xyz.onns.juc.SemaphoreTest |
完。