Semaphore: 同一时间控制并发线程数. 比如⇒⇒我们对外提供了一个工具类, 这个工具类通过Semaphore限定了只有四个线程能获取到锁, 那么不管外界开启了多少个线程来调用我们的工具类, 始终只有四个线程能运行我们的工具类, 这就是通过Semaphore来控制
CountDownLatch: CountDown表示”减少”, Latch表示”锁”, 所以就是从高往低来计数. 一个leader带5个小弟干活, 等五个小弟干完活了一起去吃饭, 那么leader就调用CountDownLatch的await()方法进入阻塞状态, 每个小弟执行完任务之后调用下CountDown()方法, 这样, 所有的小弟干完活之后leader就知道了, 然后就可以去吃饭.
CyclicBarrier: 就像是一桌酒席, 两个人都到了await() 才能开席. 只有一个人到了await()那么是没法开席的
FutureTask: 调用了FutureTask的 get 方法, 那么在没有拿到结果之前, 调用方(调用了 get 方法的线程) 会陷入阻塞状态
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
public class Work03 {
public static void main(String[] args) {
long start=System.currentTimeMillis();
// 在这里创建一个线程或线程池,
// 异步执行 下面方法
int result = sum(); //这是得到的返回值
// 确保 拿到result 并输出
System.out.println("异步计算结果为:"+result);
System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
// 然后退出main线程
}
private static int sum() {
return fibo(36);
}
private static int fibo(int a) {
if ( a < 2)
return 1;
return fibo(a-1) + fibo(a-2);
}
}
//方式一: Callable+FutureTask
class Work0301 {
public static void main(String[] args) {
long start=System.currentTimeMillis();
// 在这里创建一个线程或线程池,
// 异步执行 下面方法
int result = 0; //这是得到的返回值
FutureTask<Integer> integerFutureTask = new FutureTask<>(() -> {
//如果在这里加上 sleep(1000), 那么 main 线程就会阻塞一会
return sum();
});
new Thread(integerFutureTask).start();
try {
//如果没有异步线程去执行 task 的内容, 那么 get 就会一直阻塞, 通过阻塞来来确保能拿到 result
result = integerFutureTask.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
// 确保 拿到result 并输出
System.out.println("异步计算结果为:"+result);
System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
// 然后退出main线程
}
private static int sum() {
return fibo(36);
}
private static int fibo(int a) {
if ( a < 2)
return 1;
return fibo(a-1) + fibo(a-2);
}
}
//方式二: Semaphore
class Work0302 {
static int result = 0; //这是得到的返回值
public static void main(String[] args) {
long start=System.currentTimeMillis();
// 在这里创建一个线程或线程池,
// 异步执行 下面方法
Semaphore semaphore = new Semaphore(0);
new Thread(() -> {
result = sum();
semaphore.release();
}).start();
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 确保 拿到result 并输出
System.out.println("异步计算结果为:"+result);
System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
// 然后退出main线程
}
private static int sum() {
return fibo(36);
}
private static int fibo(int a) {
if ( a < 2)
return 1;
return fibo(a-1) + fibo(a-2);
}
}
//方式三: CountdownLatch
class Work0303 {
static int result = 0; //这是得到的返回值
public static void main(String[] args) {
long start=System.currentTimeMillis();
// 在这里创建一个线程或线程池,
// 异步执行 下面方法
//CountdownLatch 就相当于是一个leader 等着await() 手下把活(异步线程的任务)干完了countdown(),然后去吃饭(干主线程自己的活)
CountDownLatch countDownLatch = new CountDownLatch(1);
new Thread(() -> {
result = sum();
countDownLatch.countDown();
}).start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 确保 拿到result 并输出
System.out.println("异步计算结果为:"+result);
System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
// 然后退出main线程
}
private static int sum() {
return fibo(36);
}
private static int fibo(int a) {
if ( a < 2)
return 1;
return fibo(a-1) + fibo(a-2);
}
}
//方式四: CyclicBarrier
class Work0304 {
static int result = 0; //这是得到的返回值
public static void main(String[] args) {
long start=System.currentTimeMillis();
// 在这里创建一个线程或线程池,
// 异步执行 下面方法
//CyclicBarrier就像是一桌酒席, 两个人都到了await() 才能开席. 只有一个人到了await()那么是没法开席的
CyclicBarrier cyclicBarrier = new CyclicBarrier(2, ()-> {
System.out.println(String.format("%s is running the action task", Thread.currentThread().getName()));
});
new Thread(() -> {
result = sum();
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
//加上下面的 sleep, 那么肯定执行 action 的就是 main 线程了
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "myCustomThread").start();
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
// 确保 拿到result 并输出
System.out.println("异步计算结果为:"+result);
System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
// 然后退出main线程
}
private static int sum() {
return fibo(36);
}
private static int fibo(int a) {
if ( a < 2)
return 1;
return fibo(a-1) + fibo(a-2);
}
}
//其他的方法: 可以使用线程池+上面四种方法来满足需求.
|