0%

亲缘性线程池

亲缘性线程池

  • 亲缘性线程池指顺序投递多个任务后,能保证具有相同属性的任务顺序执行。

JDK默认线程池是不具有亲缘性的

  • 开源实现:simple-pool
  • 实现原理
    • KeyAffinityExecutor - 通过维护一个的映射,将相同属性的任务放进同一个队列中,使用单个线程执行单个队列中的任务,达到亲缘性的目的。
  • 存在问题思考
  • 通过key散列后,只有单线程处理任务,如何应对大量的同属性任务问题
  • 使用demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class SimplePoolTest {
/**
* 队列数
* 队列长度
* 线程池名称
*/
static KeyAffinityExecutor executor = KeyAffinityExecutor.newSerializingExecutor(50,5,"my-pool");

public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(Person.builder().id(1).data("1s").build());
personList.add(Person.builder().id(2).data("2s").build());
personList.add(Person.builder().id(1).data("11s").build());
personList.add(Person.builder().id(3).data("3s").build());
personList.add(Person.builder().id(1).data("111s").build());
personList.add(Person.builder().id(2).data("22s").build());
personList.add(Person.builder().id(3).data("33s").build());
personList.add(Person.builder().id(1).data("1111s").build());

exceteBatch(personList);

System.exit(1);
}

private static void exceteBatch(List<Person> personList){
personList.forEach(p -> executor.executeEx(p.getId(), () -> {
System.out.println(p);
}));
}

static class Person{
Integer id;

String data;

public Person(Integer id,String data){
this.id = id;
this.data = data;
}

static PersonBuilder builder(){
return new PersonBuilder();
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getData() {
return data;
}

public void setData(String data) {
this.data = data;
}

@Override
public String toString() {
return "Person{" +
"id=" + id +
", data='" + data + '\'' +
'}';
}
}

static class PersonBuilder{
Integer id;

String data;

public PersonBuilder id(Integer id){
this.id = id;
return this;
}
public PersonBuilder data(String data){
this.data = data;
return this;
}
public Person build(){
return new Person(id,data);
}
}
}