JDK LockSuppoprt源码翻译

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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

import sun.misc.Unsafe;

/**
* Basic thread blocking primitives for creating locks and other
* synchronization classes.
* 用于创建锁和其他同步类的基本线程阻塞原语。
* <p>This class associates, with each thread that uses it, a permit
* (in the sense of the {@link java.util.concurrent.Semaphore
* Semaphore} class). A call to {@code park} will return immediately
* if the permit is available, consuming it in the process; otherwise
* it <em>may</em> block. A call to {@code unpark} makes the permit
* available, if it was not already available. (Unlike with Semaphores
* though, permits do not accumulate. There is at most one.)
* 这个类与使用它的每个线程关联一个许可证(和Semaphore类差不多)。
* 如果许可证可用,对{@code park}的调用将立即返回,并在此过程中使用它;否则它可能会阻塞。
* 如果许可证尚未可用,则调用{@code unpark}将使许可证可用。
* (与信号量不同,许可证不会累积。最多只有一个)。
*
* <p>Methods {@code park} and {@code unpark} provide efficient
* means of blocking and unblocking threads that do not encounter the
* problems that cause the deprecated methods {@code Thread.suspend}
* and {@code Thread.resume} to be unusable for such purposes: Races
* between one thread invoking {@code park} and another thread trying
* to {@code unpark} it will preserve liveness, due to the
* permit. Additionally, {@code park} will return if the caller's
* thread was interrupted, and timeout versions are supported. The
* {@code park} method may also return at any other time, for "no
* reason", so in general must be invoked within a loop that rechecks
* conditions upon return. In this sense {@code park} serves as an
* optimization of a "busy wait" that does not waste as much time
* spinning, but must be paired with an {@code unpark} to be
* effective.
* 方法{@code park}和{@code unpark}提供了有效的方法来阻塞和解除阻塞线程,
* 这些线程不会遇到导致废弃方法{@code Thread.suspend}和{@code Thread.resume}不能用于这些目的的问题:
* 调用{@code park}的线程与试图{@code unpark}的线程之间的竞争将保持活跃,这是由于许可证的原因。
* 此外,如果调用者的线程被中断,并且支持超时版本,则{@code park}将interrupted。
* {@code park}方法也可以在任何其他时间返回,原因是“没有任何原因”,所以通常必须在返回时在循环中调用,循环会重新检查条件。
* 从这个意义上说,{@code park}是一个“繁忙等待”的优化,它不会浪费太多的时间旋转,但必须与{@code unpark}匹配才能有效。
*
* <p>The three forms of {@code park} each also support a
* {@code blocker} object parameter. This object is recorded while
* the thread is blocked to permit monitoring and diagnostic tools to
* identify the reasons that threads are blocked. (Such tools may
* access blockers using method {@link #getBlocker(Thread)}.)
* The use of these forms rather than the original forms without this
* parameter is strongly encouraged. The normal argument to supply as
* a {@code blocker} within a lock implementation is {@code this}.
* {@code park}的三种形式都支持{@code blocker}对象参数。
* 在线程被阻塞时记录此对象,以便允许监视和诊断工具识别线程被阻塞的原因。
* (这些工具可以使用方法{@link #getBlocker(Thread)}访问阻塞程序。)
* 强烈建议使用这些形式而不是没有此参数的原始形式。
* 在锁实现中作为{@code blocker}提供的正常参数是{@code this}。
*
* <p>These methods are designed to be used as tools for creating
* higher-level synchronization utilities, and are not in themselves
* useful for most concurrency control applications. The {@code park}
* method is designed for use only in constructions of the form:
* 这些方法被设计为用于创建更高级别的同步实用程序的工具,但它们本身并不适用于大多数并发控制应用程序。
* {@code park}方法只适用于下列结构:
* <pre> {@code
* while (!canProceed()) { ... LockSupport.park(this); }}</pre>
* <p>
* where neither {@code canProceed} nor any other actions prior to the
* call to {@code park} entail locking or blocking. Because only one
* permit is associated with each thread, any intermediary uses of
* {@code park} could interfere with its intended effects.
* 在调用{@code park}之前,{@code canProceed}或任何其他操作都不需要锁定或阻塞。
* 因为每个线程只与一个许可证相关联,所以任何中介使用{@code park}都可能干扰它的预期效果。
*
* <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
* non-reentrant lock class:
* 下面是一个先进先出非重入锁类的例子:
* <pre> {@code
* class FIFOMutex {
* //有两种状态 true或者false
* private final AtomicBoolean locked = new AtomicBoolean(false);
* //线程队列
* private final Queue<Thread> waiters
* = new ConcurrentLinkedQueue<Thread>();
*
* //加锁
* public void lock() {
* //中断标志
* boolean wasInterrupted = false;
* //当前线程
* Thread current = Thread.currentThread();
* //当前线程入队列
* waiters.add(current);
*
* // Block while not first in queue or cannot acquire lock
* //在队列中不是第一个或无法获取锁时阻塞
* while (waiters.peek() != current ||
* !locked.compareAndSet(false, true)) {
* //阻塞
* LockSupport.park(this);
* //在等待时忽略中断
* if (Thread.interrupted()) // ignore interrupts while waiting
* wasInterrupted = true;
* }
* //移除当前线程
* waiters.remove();
* //退出时重申中断状态
* if (wasInterrupted) // reassert interrupt status on exit
* current.interrupt();
* }
* 解锁
* public void unlock() {
* //解锁状态设置
* locked.set(false);
* //当前线程解锁定
* LockSupport.unpark(waiters.peek());
* }
* }}</pre>
*/
public class LockSupport {
/**
* 不能被实例化。
*/
private LockSupport() {
} // Cannot be instantiated.

/**
* Sets blocker.
*
* @param t the t
* @param arg the arg
*/
private static void setBlocker(Thread t, Object arg) {
// Even though volatile, hotspot doesn't need a write barrier here.
// 尽管hotspot是易失性的,但它并不需要写屏障。
UNSAFE.putObject(t, parkBlockerOffset, arg);
}

/**
* Makes available the permit for the given thread, if it
* was not already available. If the thread was blocked on
* {@code park} then it will unblock. Otherwise, its next call
* to {@code park} is guaranteed not to block. This operation
* is not guaranteed to have any effect at all if the given
* thread has not been started.
* 使给定线程的许可证可用(如果它还没有可用)。如果线程在{@code park}上被阻塞,那么它将解阻塞。
* 否则,它对{@code park}的下一次调用将保证不会阻塞。
* 如果没有启动给定的线程,则不能保证此操作具有任何效果。
*
* @param thread the thread to unpark, or {@code null}, in which case
* this operation has no effect 取消停靠的线程,或{@code null},在这种情况下,此操作没有效果
*/
public static void unpark(Thread thread) {
//如果线程不为空,则处理,解阻塞
if (thread != null)
UNSAFE.unpark(thread);
}

/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
* 除非有许可证,否则为线程调度目的禁用当前线程。
*
* <p>If the permit is available then it is consumed and the call returns
* immediately; otherwise
* the current thread becomes disabled for thread scheduling
* purposes and lies dormant until one of three things happens:
* 如果许可证是可用的,那么它将被使用,调用立即返回;
* 否则,当前线程将出于线程调度的目的被禁用,并处于休眠状态,直到以下三种情况之一发生:
*
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
* 其他一些线程以当前线程为目标调用{@link #unpark unpark}
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
* 其他线程中断当前线程
*
* <li>The call spuriously (that is, for no reason) returns.
* 虚假的调用(也就是说,没有理由)返回。
* </ul>
*
* <p>This method does <em>not</em> report which of these caused the
* method to return. Callers should re-check the conditions which caused
* the thread to park in the first place. Callers may also determine,
* for example, the interrupt status of the thread upon return.
* 此方法不报告是哪些原因导致该方法返回。调用者应该重新检查导致线程首先停车的条件。
* 例如,调用者还可以在返回时确定线程的中断状态。
*
* @param blocker the synchronization object responsible for this
* thread parking 负责此操作的同步对象
* @since 1.6
*/
public static void park(Object blocker) {
//获取当前线程
Thread t = Thread.currentThread();
//设置线程parkBlocker
setBlocker(t, blocker);
//阻塞线程
UNSAFE.park(false, 0L);
//清除parkBlocker
setBlocker(t, null);
}

/**
* Disables the current thread for thread scheduling purposes, for up to
* the specified waiting time, unless the permit is available.
* 除非有许可证,否则在指定的等待时间内,为线程调度目的禁用当前线程。
*
* <p>If the permit is available then it is consumed and the call
* returns immediately; otherwise the current thread becomes disabled
* for thread scheduling purposes and lies dormant until one of four
* things happens:
* 如果许可证是可用的,那么它将被使用,调用立即返回;
* 否则,当前线程将出于线程调度的目的被禁用,并处于休眠状态,直到以下四种情况之一发生:
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
* 其他一些线程以当前线程为目标调用{@link #unpark unpark}
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
* 其他线程中断当前线程
*
* <li>The specified waiting time elapses; or
* 指定的等待时间已经过了
* <li>The call spuriously (that is, for no reason) returns.
* 虚假的调用(也就是说,没有理由)返回
* </ul>
*
* <p>This method does <em>not</em> report which of these caused the
* method to return. Callers should re-check the conditions which caused
* the thread to park in the first place. Callers may also determine,
* for example, the interrupt status of the thread, or the elapsed time
* upon return.
* 此方法不报告是哪些原因导致该方法返回。调用者应该重新检查导致线程首先停车的条件。
* 例如,调用者还可以确定线程的中断状态,或者返回时的运行时间。
*
* @param blocker the synchronization object responsible for this
* thread parking 负责此操作的同步对象
* @param nanos the maximum number of nanoseconds to wait 等待的最大纳秒数
* @since 1.6
*/
public static void parkNanos(Object blocker, long nanos) {
//如果等待纳秒数大于0
if (nanos > 0) {
//获取当前线程
Thread t = Thread.currentThread();
//设置当前线程parkBlocker
setBlocker(t, blocker);
//等待nanos后阻塞线程
UNSAFE.park(false, nanos);
//清除当前线程parkBlocker
setBlocker(t, null);
}
}

/**
* Disables the current thread for thread scheduling purposes, until
* the specified deadline, unless the permit is available.
* 为线程调度目的禁用当前线程,直到指定的截止日期,除非许可证可用。
*
* <p>If the permit is available then it is consumed and the call
* returns immediately; otherwise the current thread becomes disabled
* for thread scheduling purposes and lies dormant until one of four
* things happens:
* 如果许可证是可用的,那么它将被使用,调用立即返回;
* 否则,当前线程将出于线程调度的目的被禁用,并处于休眠状态,直到以下四种情况之一发生:
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
* 其他一些线程以当前线程为目标调用{@link #unpark unpark}
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the
* current thread; or
* 其他线程中断当前线程
* <li>The specified deadline passes; or
* 指定的截止日期过了
* <li>The call spuriously (that is, for no reason) returns.
* 虚假的调用(也就是说,没有理由)返回
* </ul>
*
* <p>This method does <em>not</em> report which of these caused the
* method to return. Callers should re-check the conditions which caused
* the thread to park in the first place. Callers may also determine,
* for example, the interrupt status of the thread, or the current time
* upon return.
* 此方法不报告是哪些原因导致该方法返回。调用者应该重新检查导致线程首先停车的条件。
* 例如,调用者还可以确定线程的中断状态,或者返回时的运行时间。
*
* @param blocker the synchronization object responsible for this
* thread parking 负责此操作的同步对象
* @param deadline the absolute time, in milliseconds from the Epoch,
* to wait until 等待到的绝对时间(以毫秒为单位)
* @since 1.6
*/
public static void parkUntil(Object blocker, long deadline) {
//获取当前线程
Thread t = Thread.currentThread();
//设置当前线程parkBlocker
setBlocker(t, blocker);
//达到截止时间后阻塞线程
UNSAFE.park(true, deadline);
//清除当前线程parkBlocker
setBlocker(t, null);
}

/**
* Returns the blocker object supplied to the most recent
* invocation of a park method that has not yet unblocked, or null
* if not blocked. The value returned is just a momentary
* snapshot -- the thread may have since unblocked or blocked on a
* different blocker object.
* 返回提供给最近一次调用尚未解阻塞的park方法的blocker对象,如果没有阻塞,则返回null。
* 返回的值只是一个瞬时快照——线程可能已经在另一个blocker对象上解除了阻塞或阻塞。
*
* @param t the thread
* @return the blocker
* @throws NullPointerException if argument is null
* @since 1.6
*/
public static Object getBlocker(Thread t) {
//判空
if (t == null)
throw new NullPointerException();
//获取线程parkBlocker
return UNSAFE.getObjectVolatile(t, parkBlockerOffset);
}

/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
* 除非有许可证,否则为线程调度目的禁用当前线程。
*
* <p>If the permit is available then it is consumed and the call
* returns immediately; otherwise the current thread becomes disabled
* for thread scheduling purposes and lies dormant until one of three
* things happens:
* 如果许可证是可用的,那么它将被使用,调用立即返回;
* 否则,当前线程将出于线程调度的目的被禁用,并处于休眠状态,直到以下三种情况之一发生:
* <ul>
*
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
* 其他一些线程以当前线程为目标调用{@link #unpark unpark}
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
* 其他线程中断当前线程
*
* <li>The call spuriously (that is, for no reason) returns.
* 虚假的调用(也就是说,没有理由)返回。
* </ul>
*
* <p>This method does <em>not</em> report which of these caused the
* method to return. Callers should re-check the conditions which caused
* the thread to park in the first place. Callers may also determine,
* for example, the interrupt status of the thread upon return.
* 此方法不报告是哪些原因导致该方法返回。调用者应该重新检查导致线程首先停车的条件。
* 例如,调用者还可以在返回时确定线程的中断状态。
*/
public static void park() {
//阻塞
UNSAFE.park(false, 0L);
}

/**
* Disables the current thread for thread scheduling purposes, for up to
* the specified waiting time, unless the permit is available.
*
* <p>If the permit is available then it is consumed and the call
* returns immediately; otherwise the current thread becomes disabled
* for thread scheduling purposes and lies dormant until one of four
* things happens:
*
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
*
* <li>The specified waiting time elapses; or
*
* <li>The call spuriously (that is, for no reason) returns.
* </ul>
*
* <p>This method does <em>not</em> report which of these caused the
* method to return. Callers should re-check the conditions which caused
* the thread to park in the first place. Callers may also determine,
* for example, the interrupt status of the thread, or the elapsed time
* upon return.
*
* @param nanos the maximum number of nanoseconds to wait
*/
public static void parkNanos(long nanos) {
if (nanos > 0)
//等待nanos后锁定
UNSAFE.park(false, nanos);
}

/**
* Disables the current thread for thread scheduling purposes, until
* the specified deadline, unless the permit is available.
*
* <p>If the permit is available then it is consumed and the call
* returns immediately; otherwise the current thread becomes disabled
* for thread scheduling purposes and lies dormant until one of four
* things happens:
*
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
*
* <li>The specified deadline passes; or
*
* <li>The call spuriously (that is, for no reason) returns.
* </ul>
*
* <p>This method does <em>not</em> report which of these caused the
* method to return. Callers should re-check the conditions which caused
* the thread to park in the first place. Callers may also determine,
* for example, the interrupt status of the thread, or the current time
* upon return.
*
* @param deadline the absolute time, in milliseconds from the Epoch,
* to wait until
*/
public static void parkUntil(long deadline) {
//到截至日期后锁定
UNSAFE.park(true, deadline);
}

/**
* Returns the pseudo-randomly initialized or updated secondary seed.
* Copied from ThreadLocalRandom due to package access restrictions.
* 返回伪随机初始化或更新的辅助种子。由于包访问限制,从ThreadLocalRandom复制。
*/
static final int nextSecondarySeed() {
//threadLocalRandomSecondarySeed
int r;
//当前线程
Thread t = Thread.currentThread();
if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
r ^= r << 13; // xorshift
r ^= r >>> 17;
r ^= r << 5;
} else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
r = 1; // avoid zero
UNSAFE.putInt(t, SECONDARY, r);
return r;
}

// Hotspot implementation via intrinsics API
private static final Unsafe UNSAFE;
private static final long parkBlockerOffset;
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;

static {
try {
UNSAFE = Unsafe.getUnsafe();
Class<?> tk = Thread.class;
parkBlockerOffset = UNSAFE.objectFieldOffset
(tk.getDeclaredField("parkBlocker"));
SEED = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSeed"));
PROBE = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomProbe"));
SECONDARY = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSecondarySeed"));
} catch (Exception ex) {
throw new Error(ex);
}
}

}