Skip to content

Commit ae0a1c2

Browse files
committed
version 0.4.0.0 update
完成乐观锁开发。目前有互斥锁、读写锁、乐观锁,均已测试可用
1 parent 86e8079 commit ae0a1c2

File tree

14 files changed

+104
-15
lines changed

14 files changed

+104
-15
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,7 @@
5858
<tr>
5959
<td>0.3.3.0</td><td>完成乐观锁处理器开发,目前可以将乐观锁动态编译进入类成员</td><td>2022年1月30日</td>
6060
</tr>
61+
<tr>
62+
<td>0.4.0.0</td><td>完成乐观锁开发。目前有互斥锁、读写锁、乐观锁,均已测试可用</td><td>2022年1月30日</td>
63+
</tr>
6164
</table>

src/main/java/org/springframework/lock/annotation/EnableSpringLocks.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.springframework.context.annotation.EnableAspectJAutoProxy;
44
import org.springframework.context.annotation.Import;
5+
import org.springframework.lock.aspect.OptimisticLockAspect;
56
import org.springframework.lock.aspect.ReadLockAspect;
67
import org.springframework.lock.aspect.SynchronizedAspect;
78
import org.springframework.lock.aspect.WriteLockAspect;
@@ -14,7 +15,8 @@
1415
@Import({
1516
SynchronizedAspect.class,
1617
ReadLockAspect.class,
17-
WriteLockAspect.class
18+
WriteLockAspect.class,
19+
OptimisticLockAspect.class
1820
})
1921
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
2022
@Retention(RetentionPolicy.RUNTIME)

src/main/java/org/springframework/lock/annotation/OptimisticLock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
public @interface OptimisticLock {
1313

1414
/**
15-
* 乐观锁忙等待时间
15+
* 乐观锁忙等待毫秒数
1616
* @return 乐观锁忙等待时间
1717
*/
1818
long value() default 500L;

src/main/java/org/springframework/lock/annotation/Synchronized.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.springframework.lock.annotation;
22

3-
import org.springframework.core.annotation.AliasFor;
4-
53
import java.lang.annotation.*;
64

75
/**
@@ -13,7 +11,7 @@
1311
public @interface Synchronized {
1412

1513
/**
16-
* 用来当作锁的成员变量名,默认使用当前类的字节码当作锁,同lock
14+
* 用来当作锁的成员变量名,默认使用当前类的字节码当作锁
1715
* @return 锁对象
1816
*/
1917
String value() default "";
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* 这个包包含了该框架的全部注解.
3+
* 每个注解上都有对应的注释,写得很清楚,自己看就可以了,不加以赘述.
4+
* 需要注意的是,如果需要使锁注解生效,需要在springboot启动类上添加{@code @EnableSpringLocks}注解
5+
* @author 宗祥瑞
6+
* @version 0.5.0.0
7+
*/
8+
package org.springframework.lock.annotation;

src/main/java/org/springframework/lock/aspect/OptimisticLockAspect.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
import org.aspectj.lang.ProceedingJoinPoint;
66
import org.aspectj.lang.annotation.Around;
77
import org.aspectj.lang.annotation.Aspect;
8+
import org.aspectj.lang.reflect.MethodSignature;
9+
import org.springframework.lock.annotation.OptimisticLock;
10+
11+
import java.lang.reflect.Field;
12+
import java.lang.reflect.Method;
13+
import java.util.concurrent.atomic.AtomicBoolean;
14+
15+
import static java.lang.Thread.sleep;
816

917
/**
1018
* 乐观锁的切面
@@ -25,8 +33,48 @@ public class OptimisticLockAspect {
2533
*/
2634
@Around("@annotation(org.springframework.lock.annotation.OptimisticLock)")
2735
public Object aroundOptimisticLock(ProceedingJoinPoint jp) throws Throwable {
28-
Object result = jp.proceed();
36+
Object obj = jp.getTarget();
37+
Class<?> clz = obj.getClass();
38+
// 获取等待时长,默认500毫秒
39+
long waitTime = 500L;
40+
MethodSignature signature = (MethodSignature) jp.getSignature();
41+
Method method = signature.getMethod();
42+
if (method != null) {
43+
OptimisticLock annotation = method.getAnnotation(OptimisticLock.class);
44+
if (annotation != null) {
45+
waitTime = annotation.value();
46+
}
47+
}
48+
// 获取锁对象
49+
AtomicBoolean lock = null;
50+
for (Field field : clz.getDeclaredFields()) {
51+
if ("$opLock".equals(field.getName())){
52+
field.setAccessible(true);
53+
Object unknownLock = field.get(obj);
54+
lock = (AtomicBoolean) unknownLock;
55+
}
56+
}
57+
Object result = null;
58+
if (lock != null){
59+
while (true){
60+
if (lock.compareAndSet(true, false))
61+
// 拿到了锁
62+
break;
63+
else
64+
// 如果没拿到锁就忙等待
65+
sleep(waitTime);
66+
}
67+
try {
68+
LOGGER.info(clz.getSimpleName() + "获得乐观锁");
69+
result = jp.proceed();
70+
LOGGER.info(clz.getSimpleName() + "释放乐观锁");
71+
}finally {
72+
lock.set(true);
73+
}
74+
}else{
75+
LOGGER.warn(clz.getSimpleName() + "生成乐观锁失败,未能加锁");
76+
result = jp.proceed();
77+
}
2978
return result;
3079
}
31-
3280
}

src/main/java/org/springframework/lock/aspect/SynchronizedAspect.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
import org.apache.commons.logging.Log;
44
import org.apache.commons.logging.LogFactory;
55
import org.aspectj.lang.ProceedingJoinPoint;
6-
import org.aspectj.lang.Signature;
76
import org.aspectj.lang.annotation.Around;
87
import org.aspectj.lang.annotation.Aspect;
98
import org.aspectj.lang.reflect.MethodSignature;
10-
import org.springframework.boot.SpringApplication;
119
import org.springframework.lock.annotation.Synchronized;
1210

1311
import java.lang.reflect.Field;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* 这个包存放了注解对应的切面,用来做动态代理.
3+
* 每个切面都有注释,没什么好说的,不加以赘述.
4+
* 切面这部分需要托管到spring容器中去执行.
5+
* @author 宗祥瑞
6+
* @version 0.5.0.0
7+
*/
8+
package org.springframework.lock.aspect;

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.sun.source.tree.Tree;
55
import com.sun.tools.javac.api.JavacTrees;
66
import com.sun.tools.javac.code.Flags;
7-
import com.sun.tools.javac.code.TypeTag;
87
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
98
import com.sun.tools.javac.tree.JCTree;
109
import com.sun.tools.javac.tree.TreeMaker;
@@ -17,7 +16,6 @@
1716
import javax.lang.model.element.Element;
1817
import javax.lang.model.element.ExecutableElement;
1918
import javax.lang.model.element.TypeElement;
20-
import javax.lang.model.type.TypeKind;
2119
import javax.tools.Diagnostic;
2220
import java.util.HashSet;
2321
import java.util.Set;
@@ -120,14 +118,15 @@ public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
120118

121119
/**
122120
* 制作乐观锁
121+
* @param clz 要添加锁的类
123122
* @return 变量声明
124123
*/
125124
private JCVariableDecl makeOptimisticLock(TypeElement clz){
126125
// 导入包
127126
JCCompilationUnit imports = (JCCompilationUnit) this.javacTrees.getPath(clz).getCompilationUnit();
128127
imports.defs = imports.defs.append(this.treeMaker.Import(this.treeMaker.Select(this.treeMaker.Ident(names.fromString("java.util.concurrent.atomic")), this.names.fromString("AtomicBoolean")), false));
129128
// 声明变量
130-
JCModifiers modifiers = this.treeMaker.Modifiers(Flags.PRIVATE + Flags.FINAL);
129+
JCModifiers modifiers = this.treeMaker.Modifiers(Flags.PRIVATE + Flags.VOLATILE);
131130
JCVariableDecl var = this.treeMaker.VarDef(
132131
modifiers,
133132
this.names.fromString("$opLock"),

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.sun.source.tree.Tree;
66
import com.sun.tools.javac.api.JavacTrees;
77
import com.sun.tools.javac.code.Flags;
8-
import com.sun.tools.javac.code.Type;
98
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
109
import com.sun.tools.javac.tree.JCTree;
1110
import com.sun.tools.javac.tree.TreeMaker;
@@ -16,12 +15,10 @@
1615
import javax.lang.model.SourceVersion;
1716
import javax.lang.model.element.Element;
1817
import javax.lang.model.element.ExecutableElement;
19-
import javax.lang.model.element.Name;
2018
import javax.lang.model.element.TypeElement;
2119
import javax.tools.Diagnostic;
2220
import java.util.HashSet;
2321
import java.util.Set;
24-
import java.util.concurrent.locks.ReentrantReadWriteLock;
2522

2623
import static com.sun.tools.javac.tree.JCTree.*;
2724
import static com.sun.tools.javac.util.List.nil;
@@ -133,6 +130,7 @@ public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
133130

134131
/**
135132
* 制作读写锁
133+
* @param clz 要添加锁的类
136134
* @return 变量声明
137135
*/
138136
private JCVariableDecl makeReadWriteLock(TypeElement clz){
@@ -152,6 +150,7 @@ private JCVariableDecl makeReadWriteLock(TypeElement clz){
152150

153151
/**
154152
* 制作读锁
153+
* @param clz 要添加锁的类
155154
* @return 变量声明
156155
*/
157156
private JCVariableDecl makeReadLock(TypeElement clz){

0 commit comments

Comments
 (0)