Skip to content

Commit 7ad77c2

Browse files
committed
version 1.1.0.0 update
新增注解@MakeReadWriteLocks用于对类生成自定义读写锁,其fair属性来自于注解的类下@readlock注解或@WriteLock注解的fair属性值
1 parent d2c1cda commit 7ad77c2

5 files changed

Lines changed: 95 additions & 16 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,7 @@
8282
<tr>
8383
<td>1.0.0.0</td><td>修复时长溢出的BUG;完善乐观锁,现在可以使用自定义的乐观锁,并指定最长等待时间、最长执行时间、是否强制执行等,全方位避免死锁</td><td>2022年2月5日</td>
8484
</tr>
85+
<tr>
86+
<td>1.1.0.0</td><td>新增注解<code>@MakeReadWriteLocks</code>用于对类生成自定义读写锁,其<code>fair</code>属性来自于注解的类下<code>@ReadLock</code>注解或<code>@WriteLock</code>注解的<code>fair</code>属性值</td><td>2022年2月6日</td>
87+
</tr>
8588
</table>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.springframework.lock.annotation;
2+
3+
import java.lang.annotation.*;
4+
5+
/**
6+
* 自动生成读写锁
7+
*/
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target(ElementType.TYPE)
10+
@Documented
11+
public @interface MakeReadWriteLocks {
12+
13+
/**
14+
* 锁变量的名称,必须是合法变量名,并且不与已有变量声明重合
15+
* @return 默认无锁变量
16+
*/
17+
String[] value() default {};
18+
}

src/main/java/org/springframework/lock/processor/ReadWriteLockProcessor.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.sun.tools.javac.tree.TreeMaker;
1010
import com.sun.tools.javac.tree.TreeTranslator;
1111
import com.sun.tools.javac.util.*;
12+
import org.springframework.lock.annotation.MakeReadWriteLocks;
1213
import org.springframework.lock.annotation.ReadLock;
1314
import org.springframework.lock.annotation.WriteLock;
1415

@@ -117,6 +118,8 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
117118
}
118119
// 对每一个涉及到的类添加锁成员
119120
for (TypeElement clz : cls) {
121+
MakeReadWriteLocks makeReadWriteLocks = clz.getAnnotation(MakeReadWriteLocks.class);
122+
String[] makeLocks = makeReadWriteLocks != null ? makeReadWriteLocks.value() : new String[]{};
120123
JCTree tree = javacTrees.getTree(clz);
121124
tree.accept(new TreeTranslator() {
122125
@Override
@@ -130,15 +133,25 @@ public void visitClassDef(JCClassDecl jcClassDecl) {
130133
trees = trees.append(x);
131134
}
132135
jcClassDecl.defs = trees;
133-
messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读写锁");
134-
JCVariableDecl lock = makeReadWriteLock(clz, map.get(clz));
136+
// 生成$读写锁
137+
messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读写锁$lock");
138+
JCVariableDecl lock = makeReadWriteLock(clz, "$lock", map.get(clz));
135139
jcClassDecl.defs = jcClassDecl.defs.append(lock);
136-
messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读锁");
137-
JCVariableDecl readLock = makeReadLock(clz);
140+
messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读锁$readLock");
141+
JCVariableDecl readLock = makeReadLock(clz, "$readLock");
138142
jcClassDecl.defs = jcClassDecl.defs.append(readLock);
139-
messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成写锁");
140-
JCVariableDecl writeLock = makeWriteLock(clz);
143+
messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成写锁$writeLock");
144+
JCVariableDecl writeLock = makeWriteLock(clz, "$writeLock");
141145
jcClassDecl.defs = jcClassDecl.defs.append(writeLock);
146+
// 生成make读写锁
147+
for (String makeLock : makeLocks) {
148+
if (makeLock.length() == 0)
149+
continue;
150+
messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读写锁" + makeLock);
151+
JCVariableDecl make = makeReadWriteLock(clz, makeLock, map.get(clz));
152+
jcClassDecl.defs = jcClassDecl.defs.append(make);
153+
}
154+
142155
super.visitClassDef(jcClassDecl);
143156
}
144157
});
@@ -149,10 +162,11 @@ public void visitClassDef(JCClassDecl jcClassDecl) {
149162
/**
150163
* 制作读写锁
151164
* @param clz 要添加锁的类
165+
* @param lockName 变量名称
152166
* @param properties 注解的属性
153167
* @return 变量声明
154168
*/
155-
private JCVariableDecl makeReadWriteLock(TypeElement clz, Map<String, Object> properties) {
169+
private JCVariableDecl makeReadWriteLock(TypeElement clz, String lockName, Map<String, Object> properties) {
156170
// 导入包
157171
JCCompilationUnit imports = (JCCompilationUnit) this.javacTrees.getPath(clz).getCompilationUnit();
158172
imports.defs = imports.defs.append(this.treeMaker.Import(this.treeMaker.Select(this.treeMaker.Ident(names.fromString("java.util.concurrent.locks")), this.names.fromString("ReentrantReadWriteLock")), false));
@@ -161,7 +175,7 @@ private JCVariableDecl makeReadWriteLock(TypeElement clz, Map<String, Object> pr
161175
if (properties.get("fair") != null)
162176
return this.treeMaker.VarDef(
163177
modifiers,
164-
this.names.fromString("$lock"),
178+
this.names.fromString(lockName),
165179
this.memberAccess("java.util.concurrent.locks.ReentrantReadWriteLock"),
166180
this.treeMaker.NewClass(null, of(memberAccess("java.lang.Boolean")), treeMaker.Ident(names.fromString("ReentrantReadWriteLock")), of(this.treeMaker.Literal(properties.get("fair"))), null)
167181
);
@@ -177,17 +191,18 @@ private JCVariableDecl makeReadWriteLock(TypeElement clz, Map<String, Object> pr
177191
/**
178192
* 制作读锁
179193
* @param clz 要添加锁的类
194+
* @param lockName 变量名称
180195
* @return 变量声明
181196
*/
182-
private JCVariableDecl makeReadLock(TypeElement clz) {
197+
private JCVariableDecl makeReadLock(TypeElement clz, String lockName) {
183198
// 导入包
184199
JCCompilationUnit imports = (JCCompilationUnit) this.javacTrees.getPath(clz).getCompilationUnit();
185200
imports.defs = imports.defs.append(this.treeMaker.Import(this.treeMaker.Select(this.treeMaker.Ident(names.fromString("java.util.concurrent.locks")), this.names.fromString("Lock")), false));
186201
// 声明变量
187202
JCModifiers modifiers = this.treeMaker.Modifiers(Flags.PRIVATE + Flags.FINAL);
188203
JCVariableDecl var = this.treeMaker.VarDef(
189204
modifiers,
190-
this.names.fromString("$readLock"),
205+
this.names.fromString(lockName),
191206
this.memberAccess("java.util.concurrent.locks.Lock"),
192207
treeMaker.Apply(nil(), treeMaker.Select(treeMaker.Ident(names.fromString("$lock")), names.fromString("readLock")), nil())
193208
);
@@ -197,17 +212,18 @@ private JCVariableDecl makeReadLock(TypeElement clz) {
197212
/**
198213
* 制作写锁
199214
* @param clz 要添加锁的类
215+
* @param lockName 变量名称
200216
* @return 写锁变量声明
201217
*/
202-
private JCVariableDecl makeWriteLock(TypeElement clz){
218+
private JCVariableDecl makeWriteLock(TypeElement clz, String lockName){
203219
// 导入包
204220
JCCompilationUnit imports = (JCCompilationUnit) this.javacTrees.getPath(clz).getCompilationUnit();
205221
imports.defs = imports.defs.append(this.treeMaker.Import(this.treeMaker.Select(this.treeMaker.Ident(names.fromString("java.util.concurrent.locks")), this.names.fromString("Lock")), false));
206222
// 声明变量
207223
JCModifiers modifiers = this.treeMaker.Modifiers(Flags.PRIVATE + Flags.FINAL);
208224
JCVariableDecl var = this.treeMaker.VarDef(
209225
modifiers,
210-
this.names.fromString("$writeLock"),
226+
this.names.fromString(lockName),
211227
this.memberAccess("java.util.concurrent.locks.Lock"),
212228
treeMaker.Apply(nil(), treeMaker.Select(treeMaker.Ident(names.fromString("$lock")), names.fromString("writeLock")), nil())
213229
);

src/test/java/example/name/controller/BaseController.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,18 @@ public String testOptimisticLock(){
5555
String result = this.baseService.testOptimisticLock();
5656
return result;
5757
}
58+
59+
@RequestMapping(value = "/testMakeLockWrite", method = RequestMethod.GET)
60+
@ResponseBody
61+
public String testMakeLockWrite(){
62+
String result = this.baseService.testMakeLockWrite();
63+
return result;
64+
}
65+
66+
@RequestMapping(value = "/testMakeLockRead", method = RequestMethod.GET)
67+
@ResponseBody
68+
public String testMakeLockRead(){
69+
String result = this.baseService.testMakeLockRead();
70+
return result;
71+
}
5872
}

src/test/java/example/name/service/BaseService.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22

33
import org.apache.commons.logging.Log;
44
import org.apache.commons.logging.LogFactory;
5-
import org.springframework.lock.annotation.OptimisticLock;
6-
import org.springframework.lock.annotation.ReadLock;
7-
import org.springframework.lock.annotation.Synchronized;
8-
import org.springframework.lock.annotation.WriteLock;
5+
import org.springframework.lock.annotation.*;
96
import org.springframework.stereotype.Service;
107

118
import static org.springframework.lock.enumeration.BooleanEnum.*;
129

1310

1411
@Service
12+
@MakeReadWriteLocks({
13+
"myLock1",
14+
"myLock2",
15+
"myLock3"
16+
})
1517
public class BaseService {
1618

1719
private static final Log LOGGER = LogFactory.getLog(BaseService.class);
@@ -99,4 +101,30 @@ public String testOptimisticLock2(){
99101
LOGGER.info(name + "执行结束");
100102
return "testOptimisticLock2 执行结束";
101103
}
104+
105+
@ReadLock("myLock1")
106+
public String testMakeLockRead(){
107+
String name = Thread.currentThread().getName();
108+
LOGGER.info(name + "开始执行");
109+
try {
110+
Thread.sleep(5000);
111+
} catch (InterruptedException e) {
112+
e.printStackTrace();
113+
}
114+
LOGGER.info(name + "执行结束");
115+
return "testMakeLockRead 执行结束";
116+
}
117+
118+
@WriteLock("myLock1")
119+
public String testMakeLockWrite(){
120+
String name = Thread.currentThread().getName();
121+
LOGGER.info(name + "开始执行");
122+
try {
123+
Thread.sleep(5000);
124+
} catch (InterruptedException e) {
125+
e.printStackTrace();
126+
}
127+
LOGGER.info(name + "执行结束");
128+
return "testMakeLockWrite 执行结束";
129+
}
102130
}

0 commit comments

Comments
 (0)