queue = new LinkedBlockingQueue<>();
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ queue.addAll(instanceId);
+ }
+ }).start();
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < size; i++) {
+
+ }
+ }
+ }).start();
+ }
+}
diff --git a/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/DelayQueueDemo.java b/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/DelayQueueDemo.java
new file mode 100644
index 0000000..bdf698a
--- /dev/null
+++ b/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/DelayQueueDemo.java
@@ -0,0 +1,16 @@
+package cn.whaifree.tech.demo.thread;
+
+import java.util.concurrent.*;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/5 14:24
+ * @注释
+ */
+public class DelayQueueDemo {
+
+ public static void main(String[] args) {
+
+ }
+}
diff --git a/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/FutureRelative.java b/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/FutureRelative.java
index 83e71e5..43f69ab 100644
--- a/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/FutureRelative.java
+++ b/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/FutureRelative.java
@@ -17,9 +17,14 @@ public class FutureRelative {
final static ExecutorService executorService = Executors.newFixedThreadPool(10,
Executors.defaultThreadFactory());
+ final static ExecutorService executorService1 = Executors.newScheduledThreadPool(10);
+
+
+
public static void main(String[] args) {
- futureTaskDemo();
+
+// futureTaskDemo();
}
diff --git a/ForJdk17/src/test/java/org/example/AppTest.java b/ForJdk17/src/test/java/org/example/AppTest.java
index d5f435d..da1f544 100644
--- a/ForJdk17/src/test/java/org/example/AppTest.java
+++ b/ForJdk17/src/test/java/org/example/AppTest.java
@@ -1,4 +1,4 @@
-package org.example;
+package com.whai;
import junit.framework.Test;
import junit.framework.TestCase;
diff --git a/ForJdk8/pom.xml b/ForJdk8/pom.xml
index bec8e25..343ff14 100644
--- a/ForJdk8/pom.xml
+++ b/ForJdk8/pom.xml
@@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- org.example
+ com.whai
LeetCode
1.0-SNAPSHOT
diff --git a/ForJdk8/src/main/java/cn/whaifree/tech/FunctionInterfaceDemo.java b/ForJdk8/src/main/java/cn/whaifree/tech/FunctionInterfaceDemo.java
index a0da3cc..72422e6 100644
--- a/ForJdk8/src/main/java/cn/whaifree/tech/FunctionInterfaceDemo.java
+++ b/ForJdk8/src/main/java/cn/whaifree/tech/FunctionInterfaceDemo.java
@@ -1,6 +1,7 @@
package cn.whaifree.tech;
import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
/**
diff --git a/ForJdk8/src/test/java/org/example/AppTest.java b/ForJdk8/src/test/java/org/example/AppTest.java
index e027d94..d4e2014 100644
--- a/ForJdk8/src/test/java/org/example/AppTest.java
+++ b/ForJdk8/src/test/java/org/example/AppTest.java
@@ -1,4 +1,4 @@
-package org.example;
+package com.whai;
import junit.framework.Test;
import junit.framework.TestCase;
diff --git a/SeleniumDemo/pom.xml b/SeleniumDemo/pom.xml
index 25f97ec..c1e3d0a 100644
--- a/SeleniumDemo/pom.xml
+++ b/SeleniumDemo/pom.xml
@@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- org.example
+ com.whai
LeetCode
1.0-SNAPSHOT
diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/SpringDemoApplication.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/SpringDemoApplication.java
index 8e9b70c..a164470 100644
--- a/SpringDemo/src/main/java/cn/whaifree/springdemo/SpringDemoApplication.java
+++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/SpringDemoApplication.java
@@ -2,8 +2,10 @@ package cn.whaifree.springdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
+@EnableAspectJAutoProxy
public class SpringDemoApplication {
public static void main(String[] args) {
diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/BuinessException.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/BuinessException.java
new file mode 100644
index 0000000..d8f93a4
--- /dev/null
+++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/BuinessException.java
@@ -0,0 +1,22 @@
+package cn.whaifree.springdemo.controller.interceptRetry;
+
+import lombok.Getter;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/10 15:26
+ * @注释
+ */
+public class BuinessException extends RuntimeException {
+ @Getter
+ private ErrorType type;
+ private Integer code;
+
+
+ public BuinessException(ErrorType type, Integer code) {
+ this.type = type;
+ this.code = code;
+ }
+}
+
diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/ErrorType.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/ErrorType.java
new file mode 100644
index 0000000..9040b34
--- /dev/null
+++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/ErrorType.java
@@ -0,0 +1,18 @@
+package cn.whaifree.springdemo.controller.interceptRetry;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/10 15:26
+ * @注释
+ */
+public enum ErrorType {
+ RetryType("Retry Too Many", 503);
+
+ private String type;
+ private Integer code;
+ ErrorType (String type, Integer code) {
+ this.type = type;
+ this.code = code;
+ }
+}
diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/RetryController.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/RetryController.java
new file mode 100644
index 0000000..d34b204
--- /dev/null
+++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/RetryController.java
@@ -0,0 +1,24 @@
+package cn.whaifree.springdemo.controller.interceptRetry;
+
+import cn.whaifree.springdemo.controller.interceptRetry.aspect.RetryLimit;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/9 21:56
+ * @注释
+ */
+@RestController
+public class RetryController {
+
+ @PostMapping("/try")
+ @RetryLimit(limitCount = 3, limitTime = 1, limitKey = "ip", resMsg = "retry请求频繁")
+ public String tryMethod(int success) {
+ if (success == 1) {
+ throw new BuinessException(ErrorType.RetryType, 500);
+ }
+ return "tryMethod";
+ }
+}
diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryAspect.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryAspect.java
new file mode 100644
index 0000000..27640b6
--- /dev/null
+++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryAspect.java
@@ -0,0 +1,146 @@
+package cn.whaifree.springdemo.controller.interceptRetry.aspect;
+
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.extra.servlet.ServletUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.hutool.http.HttpUtil;
+import cn.whaifree.springdemo.controller.interceptRetry.BuinessException;
+import cn.whaifree.springdemo.controller.interceptRetry.ErrorType;
+import com.github.benmanes.caffeine.cache.Cache;
+
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.google.common.collect.Maps;
+import com.mysql.cj.util.LogUtils;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.Getter;
+import org.apache.catalina.util.RequestUtil;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.ServletRequestUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.util.WebUtils;
+
+import java.lang.reflect.Method;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/9 21:57
+ * @注释
+ */
+@Aspect
+@Component
+@Order(100)
+public class RetryAspect {
+
+ /**
+ * 一个Cache只能有一个有效期,
+ * 所以要根据有效期进行分组
+ *
+ * 【exprieTime,【keyOfIp,time】】
+ *
+ *
+ * 对不同时间用不同cache实现
+ */
+ Map> cacheMap = new HashMap<>();
+
+ @Resource
+ @Lazy
+ private ApplicationContext applicationContext;
+
+ @PostConstruct
+ public void init() {
+ String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
+ for (String beanDefinitionName : beanDefinitionNames) {
+ // 这里有疑问,可能拿到RetryAspect走getBean导致循环依赖,RetryAspect循环依赖RetryAspect
+ if (beanDefinitionName.equalsIgnoreCase(this.getClass().getSimpleName())) {
+ continue;
+ }
+ Object bean = applicationContext.getBean(beanDefinitionName);
+
+ Method[] methods = bean.getClass().getDeclaredMethods();
+ for (Method method : methods) {
+ try {
+ // 手动用反射获取不到注解
+ RetryLimit retryLimit = AnnotationUtils.findAnnotation(method, RetryLimit.class);
+// RetryLimit retryLimit = method.getAnnotation(RetryLimit.class);
+ if (retryLimit == null) {
+ continue;
+ }
+ int expireTime = retryLimit.limitTime();
+ Cache build = Caffeine.newBuilder().expireAfterAccess(Duration.ofMinutes(expireTime)).maximumSize(1000).build();
+ cacheMap.put(expireTime, build);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+ System.out.println(cacheMap);
+ }
+
+
+
+ @Around("@annotation(cn.whaifree.springdemo.controller.interceptRetry.aspect.RetryLimit)")
+ public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
+ // 获取方法签名,设置方法可以访问
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ Method method = signature.getMethod();
+ method.setAccessible(true);
+
+ // 获取注解
+ RetryLimit retryAn = AnnotationUtils.findAnnotation(method, RetryLimit.class);
+ if (retryAn == null) {
+ return joinPoint.proceed();
+ }
+
+ // 如果包含注解,放入缓存,key为ip或者其他限流key,value为次数
+ Cache cache = cacheMap.get(retryAn.limitTime());
+ String limitKey = retryAn.limitKey();
+ if (limitKey == null || limitKey.equals("ip")) {
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request = requestAttributes.getRequest();
+ limitKey = request.getRemoteAddr();
+ }else if (limitKey.equals("userId")) {
+ // 其他策略
+ }
+ // 如果缓存中没有这个ip访问过,初始化为0
+ AtomicInteger atomicInteger = cache.get(limitKey, s -> new AtomicInteger(0));
+ if (atomicInteger.intValue() >= retryAn.limitCount()) {
+ throw new RuntimeException(retryAn.resMsg());
+ }
+
+ try {
+ return joinPoint.proceed();
+ } catch (BuinessException e) {
+ // 如果不是验证错误,向上抛出
+ if (!e.getType().equals(ErrorType.RetryType)) {
+ throw e;
+ }
+ // 如果验证错误,对atomic++
+ atomicInteger.incrementAndGet();
+ String msg = retryAn.resMsg() + ",重试次数:" + atomicInteger.intValue();
+ throw new RuntimeException(msg);
+ }
+ }
+
+
+}
diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryLimit.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryLimit.java
new file mode 100644
index 0000000..69ab419
--- /dev/null
+++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryLimit.java
@@ -0,0 +1,26 @@
+package cn.whaifree.springdemo.controller.interceptRetry.aspect;
+
+import cn.whaifree.springdemo.controller.interceptRetry.ErrorType;
+import cn.whaifree.springdemo.utils.ResVo;
+import org.springframework.data.redis.connection.ReturnType;
+
+import java.lang.annotation.*;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/9 21:57
+ * @注释
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RetryLimit {
+
+ int limitCount() default 3;
+ int limitTime() default 60;
+ String limitKey() default "ip";
+ String resMsg() default "请求过于频繁";
+ ErrorType errorType() default ErrorType.RetryType;
+
+}
diff --git a/SpringDemo/src/main/resources/application.yaml b/SpringDemo/src/main/resources/application.yaml
index 82e4781..96996c2 100644
--- a/SpringDemo/src/main/resources/application.yaml
+++ b/SpringDemo/src/main/resources/application.yaml
@@ -8,7 +8,7 @@ my:
spring:
datasource:
- url: jdbc:mysql://localhost:3306/springTest?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
+ url: jdbc:mysql://localhost:3306/springTest?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
diff --git a/pom.xml b/pom.xml
index 575f05c..7d5d5f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,10 +4,10 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- org.example
+ com.whai
LeetCode
1.0-SNAPSHOT
- jar
+ pom
ForJdk8
ForJdk17
diff --git a/sdoih.bpmn b/sdoih.bpmn
new file mode 100644
index 0000000..440f9af
--- /dev/null
+++ b/sdoih.bpmn
@@ -0,0 +1,2 @@
+
+