Skip to content

Commit 4636747

Browse files
committed
fj first test
1 parent 7f01f1a commit 4636747

File tree

3 files changed

+263
-70
lines changed

3 files changed

+263
-70
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package thread.pool;
2+
3+
import java.util.concurrent.ForkJoinPool;
4+
5+
/**
6+
* 探究Fork/Join 线程池使用场景
7+
*
8+
* @author Kuangcp
9+
* 2024-11-27 11:00
10+
* @see ForkJoinPool#makeCommonPool()
11+
*/
12+
public class ForkJoinUsePool {
13+
14+
15+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package thread.pool;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.junit.Test;
5+
6+
import java.util.concurrent.Executors;
7+
import java.util.concurrent.ForkJoinPool;
8+
import java.util.concurrent.ForkJoinTask;
9+
import java.util.concurrent.ScheduledExecutorService;
10+
import java.util.concurrent.TimeUnit;
11+
12+
/**
13+
* 测试 栈的默认 LIFO 策略
14+
*
15+
* @author Kuangcp
16+
* 2024-12-05 13:43
17+
*/
18+
@Slf4j
19+
public class ForkJoinUsePoolLIFOTest {
20+
21+
// TODO 栈出现长阻塞时的响应情况
22+
23+
24+
// [Fork join并发框架与工作窃取算法剖析-腾讯云开发者社区-腾讯云](https://cloud.tencent.com/developer/article/1512982)
25+
26+
/**
27+
* taskset -c 0,1,2 shell(复制自IDE第一行,需要IDE编译成class才会生效新改动)
28+
*
29+
* @see ForkJoinPool#externalPush(ForkJoinTask) 为什么任务只堆积在了一个队列上,因为实现中的随机数是取的提交线程,因此所有任务都堆在一个队列上了 但是为什么发生了工作窃取,任务执行顺序还是没变
30+
*/
31+
@Test
32+
public void testLIFO() throws Exception {
33+
ForkJoinPool pool = ForkJoinPool.commonPool();
34+
35+
for (int i = 0; i < 10000; i++) {
36+
int finalI = i;
37+
pool.submit(() -> {
38+
try {
39+
TimeUnit.SECONDS.sleep(2);
40+
log.info("i={}", finalI);
41+
} catch (Exception e) {
42+
log.error("", e);
43+
}
44+
});
45+
}
46+
47+
ScheduledExecutorService sche = Executors.newScheduledThreadPool(1);
48+
sche.scheduleAtFixedRate(() -> {
49+
int parallelism = pool.getParallelism();
50+
long queuedTaskCount = pool.getQueuedSubmissionCount();
51+
log.info("con={} wait={}", parallelism, queuedTaskCount);
52+
}, 1, 1, TimeUnit.SECONDS);
53+
54+
Thread.currentThread().join();
55+
}
56+
57+
/**
58+
* 加了第二个线程提交任务后,类似LIFO的效果出来了 第二批优先第一批消费
59+
*/
60+
@Test
61+
public void testLIFO2() throws Exception {
62+
ForkJoinPool pool = ForkJoinPool.commonPool();
63+
64+
for (int i = 0; i < 10000; i++) {
65+
int finalI = i;
66+
pool.submit(() -> {
67+
try {
68+
TimeUnit.SECONDS.sleep(2);
69+
log.info("first={}", finalI);
70+
} catch (Exception e) {
71+
log.error("", e);
72+
}
73+
});
74+
}
75+
76+
TimeUnit.SECONDS.sleep(3);
77+
new Thread(() -> {
78+
for (int i = 0; i < 1000; i++) {
79+
int finalI = i;
80+
pool.submit(() -> {
81+
try {
82+
TimeUnit.SECONDS.sleep(2);
83+
log.info("second={}", finalI);
84+
} catch (Exception e) {
85+
log.error("", e);
86+
}
87+
});
88+
}
89+
}).start();
90+
91+
ScheduledExecutorService sche = Executors.newScheduledThreadPool(1);
92+
sche.scheduleAtFixedRate(() -> {
93+
int parallelism = pool.getParallelism();
94+
long queuedTaskCount = pool.getQueuedSubmissionCount();
95+
log.info("con={} wait={}", parallelism, queuedTaskCount);
96+
}, 1, 1, TimeUnit.SECONDS);
97+
98+
Thread.currentThread().join();
99+
}
100+
101+
/**
102+
* 加了更多线程提交任务后,类似LIFO的效果更明显了
103+
*/
104+
@Test
105+
public void testLIFO3() throws Exception {
106+
ForkJoinPool pool = ForkJoinPool.commonPool();
107+
108+
for (int i = 0; i < 10000; i++) {
109+
int finalI = i;
110+
pool.submit(() -> {
111+
try {
112+
TimeUnit.SECONDS.sleep(2);
113+
log.info("first={}", finalI);
114+
} catch (Exception e) {
115+
log.error("", e);
116+
}
117+
});
118+
}
119+
120+
TimeUnit.SECONDS.sleep(3);
121+
for (int i = 0; i < 1000; i++) {
122+
int finalI = i;
123+
new Thread(() -> pool.submit(() -> {
124+
try {
125+
TimeUnit.SECONDS.sleep(2);
126+
log.info("{}={}", finalI, finalI);
127+
} catch (Exception e) {
128+
log.error("", e);
129+
}
130+
})).start();
131+
}
132+
133+
ScheduledExecutorService sche = Executors.newScheduledThreadPool(1);
134+
sche.scheduleAtFixedRate(() -> {
135+
int parallelism = pool.getParallelism();
136+
long queuedTaskCount = pool.getQueuedSubmissionCount();
137+
log.info("con={} wait={}", parallelism, queuedTaskCount);
138+
}, 1, 1, TimeUnit.SECONDS);
139+
140+
Thread.currentThread().join();
141+
}
142+
143+
/**
144+
* 全部新线程提交任务后,总体规律是有序的,局部是无序的,没有LIFO特性
145+
*/
146+
@Test
147+
public void testLIFO4() throws Exception {
148+
ForkJoinPool pool = ForkJoinPool.commonPool();
149+
150+
for (int i = 0; i < 1000; i++) {
151+
int finalI = i;
152+
new Thread(() -> pool.submit(() -> {
153+
try {
154+
TimeUnit.SECONDS.sleep(2);
155+
log.info("{}", finalI);
156+
} catch (Exception e) {
157+
log.error("", e);
158+
}
159+
})).start();
160+
}
161+
162+
ScheduledExecutorService sche = Executors.newScheduledThreadPool(1);
163+
sche.scheduleAtFixedRate(() -> {
164+
int parallelism = pool.getParallelism();
165+
long queuedTaskCount = pool.getQueuedSubmissionCount();
166+
log.info("con={} wait={}", parallelism, queuedTaskCount);
167+
}, 1, 1, TimeUnit.SECONDS);
168+
169+
Thread.currentThread().join();
170+
}
171+
172+
173+
@Test
174+
public void testSSSS() throws Exception {
175+
System.out.println("xxxxx");
176+
}
177+
}
Lines changed: 71 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package com.github.kuangcp.validation;
22

3+
import lombok.extern.slf4j.Slf4j;
4+
5+
import javax.validation.ConstraintViolation;
6+
import javax.validation.Validation;
7+
import javax.validation.Validator;
8+
import javax.validation.ValidatorFactory;
39
import java.util.Arrays;
410
import java.util.Collection;
511
import java.util.Collections;
@@ -8,11 +14,6 @@
814
import java.util.Map;
915
import java.util.Objects;
1016
import java.util.Set;
11-
import javax.validation.ConstraintViolation;
12-
import javax.validation.Validation;
13-
import javax.validation.Validator;
14-
import javax.validation.ValidatorFactory;
15-
import lombok.extern.slf4j.Slf4j;
1617

1718
/**
1819
* 基于注解的校验, @NotBlank @NotEmpty....
@@ -21,76 +22,76 @@
2122
@Slf4j
2223
public abstract class BeanValidator {
2324

24-
private static final ValidatorFactory validatorFactory = Validation
25-
.buildDefaultValidatorFactory();
25+
private static final ValidatorFactory validatorFactory = Validation
26+
.buildDefaultValidatorFactory();
2627

27-
/**
28-
* 校验多个字段
29-
*
30-
* @param t 校验的对象
31-
* @param groups Class, 必须要传,如果没有就传入一个new Class[0]
32-
* @param <T> 校验的对象泛型
33-
* @return key: 字段,value:错误信息
34-
*/
35-
public static <T> Map<String, String> validate(T t, Class... groups) {
36-
Validator validator = validatorFactory.getValidator();
37-
Set<ConstraintViolation<T>> violationSet = validator.validate(t, groups);
38-
if (violationSet.isEmpty()) {
39-
return Collections.emptyMap();
40-
} else {
41-
Map<String, String> errors = new HashMap<>();
42-
for (ConstraintViolation<T> violation : violationSet) {
43-
errors.put(violation.getPropertyPath().toString(), violation.getMessage());
44-
}
45-
return errors;
28+
/**
29+
* 校验多个字段
30+
*
31+
* @param t 校验的对象
32+
* @param groups Class, 必须要传,如果没有就传入一个new Class[0]
33+
* @param <T> 校验的对象泛型
34+
* @return key: 字段,value:错误信息
35+
*/
36+
public static <T> Map<String, String> validate(T t, Class... groups) {
37+
Validator validator = validatorFactory.getValidator();
38+
Set<ConstraintViolation<T>> violationSet = validator.validate(t, groups);
39+
if (violationSet.isEmpty()) {
40+
return Collections.emptyMap();
41+
} else {
42+
Map<String, String> errors = new HashMap<>();
43+
for (ConstraintViolation<T> violation : violationSet) {
44+
errors.put(violation.getPropertyPath().toString(), violation.getMessage());
45+
}
46+
return errors;
47+
}
4648
}
47-
}
4849

49-
/**
50-
* 校验多个对象
51-
*
52-
* @param collection 集合
53-
* @return key: 字段,value:错误信息
54-
*/
55-
public static Map<String, String> validateList(Collection<?> collection) {
56-
Iterator<?> iterator = collection.iterator();
57-
Map<String, String> errors;
58-
do {
59-
if (!iterator.hasNext()) {
60-
return Collections.emptyMap();
61-
}
62-
Object object = iterator.next();
63-
// new Class[0] 必须要传, 否则在determineGroupValidationOrder方法中,会抛出异常
64-
errors = validate(object, new Class[0]);
65-
} while (errors.isEmpty());
66-
return errors;
67-
}
50+
/**
51+
* 校验多个对象
52+
*
53+
* @param collection 集合
54+
* @return key: 字段,value:错误信息
55+
*/
56+
public static Map<String, String> validateList(Collection<?> collection) {
57+
Iterator<?> iterator = collection.iterator();
58+
Map<String, String> errors;
59+
do {
60+
if (!iterator.hasNext()) {
61+
return Collections.emptyMap();
62+
}
63+
Object object = iterator.next();
64+
// new Class[0] 必须要传, 否则在determineGroupValidationOrder方法中,会抛出异常
65+
errors = validate(object, new Class[0]);
66+
} while (errors.isEmpty());
67+
return errors;
68+
}
6869

69-
/**
70-
* 综合validateList 和 validate 方法, 任何校验只需要使用这个方法就可以
71-
*
72-
* @param first 第一个对象
73-
* @param objects 对象数组
74-
* @return key: 字段,value:错误信息
75-
*/
76-
public static Map<String, String> validateObject(Object first, Object... objects) {
77-
if (objects != null && objects.length > 0) {
78-
return validateList(Arrays.asList(first, objects));
79-
} else {
80-
// new Class[0] 必须要传, 否则在determineGroupValidationOrder方法中,会抛出异常
81-
return validate(first, new Class[0]);
70+
/**
71+
* 综合validateList 和 validate 方法, 任何校验只需要使用这个方法就可以
72+
*
73+
* @param first 第一个对象
74+
* @param objects 对象数组
75+
* @return key: 字段,value:错误信息
76+
*/
77+
public static Map<String, String> validateObject(Object first, Object... objects) {
78+
if (objects != null && objects.length > 0) {
79+
return validateList(Arrays.asList(first, objects));
80+
} else {
81+
// new Class[0] 必须要传, 否则在determineGroupValidationOrder方法中,会抛出异常
82+
return validate(first, new Class[0]);
83+
}
8284
}
83-
}
8485

85-
/**
86-
* 再次封装校验,对于异常直接抛出
87-
*
88-
* @param param 参数
89-
*/
90-
public static void check(Object param) throws IllegalArgumentException {
91-
Map<String, String> validateMap = BeanValidator.validateObject(param);
92-
if (Objects.nonNull(validateMap) && !validateMap.isEmpty()) {
93-
throw new RuntimeException(validateMap.values().iterator().next());
86+
/**
87+
* 再次封装校验,对于异常直接抛出
88+
*
89+
* @param param 参数
90+
*/
91+
public static void check(Object param) throws IllegalArgumentException {
92+
Map<String, String> validateMap = BeanValidator.validateObject(param);
93+
if (Objects.nonNull(validateMap) && !validateMap.isEmpty()) {
94+
throw new RuntimeException(validateMap.values().iterator().next());
95+
}
9496
}
95-
}
9697
}

0 commit comments

Comments
 (0)