Preface:
Since Groovy 1.7.3 we have a new AST transformation: @Synchronized. This annotation is based on the Project Lombok Synchronized annotation. We can use the annotation on instance and static methods. The annotation will create a lock variable in our class (or we can use an existing variable) and the code is synchronized on that lock variable. Normally with the synchronized keyword the lock is on this, but that can have side-effects.
Example:
接著來看範例代碼, 知道 @Synchronized 使用的差別. 首先參考代碼如下:
- import groovy.transform.Synchronized
- class ThdImpt implements Runnable{
- public static List
Output = new ArrayList() - public static int NEXT = 0
- public int runTimes
- public static NEXT()
- {
- return NEXT++;
- }
- public ThdImpt(int rt){runTimes = rt}
- @Override
- public void run() {
- runTimes.times {
- def next = NEXT()
- synchronized(Output)
- {
- Output.add(next);
- }
- }
- }
- }
- int ThreadOpenCount = 10
- ThreadGroup tg = new ThreadGroup()
- ThreadOpenCount.times {
- new Thread(tg, new ThdImpt(100)).start()
- }
- while(tg.activeCount() > 0) sleep(100)
- printf "\t[Info] Done (%d)!\n", ThdImpt.Output.size();
- Set
intSet = new TreeSet () - ThdImpt.Output.each { num->
- if(num==null)
- {
- printf "Contain null data!\n"
- return
- }
- if(!intSet.add(num))
- {
- printf "%d is duplicate!\n", num
- }
- }
此時 ThreadA 與 ThreadB 就會拿到相同的 NEXT=0. 因此我們需要對 NEXT() API 進行 Synchronization. 在 Groovy 可以使用 @Synchronized 在 static 函數, 確保該函數每次只能被一個線程執行以避免 Race condition. 也就是說在 NEXT() API 加上 @Synchronized 便可以解決 "??? is duplicate" 的問題.
Supplement:
* JavaTutorial - Synchronized Methods
* Java Synchronized Blocks
* Groovy groovy.transform.Synchronized annotation
沒有留言:
張貼留言