53 |
|
* switching to locking mode. While conceptually straightforward, |
54 |
|
* expressing these ideas can be verbose. For example: |
55 |
|
* |
56 |
< |
* <pre> {@code |
56 |
> |
* <pre> {@code |
57 |
|
* class Point { |
58 |
< |
* private volatile double x, y; |
59 |
< |
* private final SequenceLock sl = new SequenceLock(); |
58 |
> |
* private volatile double x, y; |
59 |
> |
* private final SequenceLock sl = new SequenceLock(); |
60 |
|
* |
61 |
< |
* void move(double deltaX, double deltaY) { // an exclusively locked method |
62 |
< |
* sl.lock(); |
63 |
< |
* try { |
64 |
< |
* x += deltaX; |
65 |
< |
* y += deltaY; |
66 |
< |
* } finally { |
67 |
< |
* sl.unlock(); |
68 |
< |
* } |
69 |
< |
* } |
61 |
> |
* // an exclusively locked method |
62 |
> |
* void move(double deltaX, double deltaY) { |
63 |
> |
* sl.lock(); |
64 |
> |
* try { |
65 |
> |
* x += deltaX; |
66 |
> |
* y += deltaY; |
67 |
> |
* } finally { |
68 |
> |
* sl.unlock(); |
69 |
> |
* } |
70 |
> |
* } |
71 |
|
* |
72 |
< |
* double distanceFromOriginV1() { // A read-only method |
73 |
< |
* double currentX, currentY; |
74 |
< |
* long seq; |
75 |
< |
* do { |
76 |
< |
* seq = sl.awaitAvailability(); |
77 |
< |
* currentX = x; |
78 |
< |
* currentY = y; |
79 |
< |
* } while (sl.getSequence() != seq); // retry if sequence changed |
80 |
< |
* return Math.sqrt(currentX * currentX + currentY * currentY); |
81 |
< |
* } |
72 |
> |
* // A read-only method |
73 |
> |
* double distanceFromOriginV1() { |
74 |
> |
* double currentX, currentY; |
75 |
> |
* long seq; |
76 |
> |
* do { |
77 |
> |
* seq = sl.awaitAvailability(); |
78 |
> |
* currentX = x; |
79 |
> |
* currentY = y; |
80 |
> |
* } while (sl.getSequence() != seq); // retry if sequence changed |
81 |
> |
* return Math.sqrt(currentX * currentX + currentY * currentY); |
82 |
> |
* } |
83 |
|
* |
84 |
< |
* double distanceFromOriginV2() { // Uses bounded retries before locking |
85 |
< |
* double currentX, currentY; |
86 |
< |
* long seq; |
87 |
< |
* int retries = RETRIES_BEFORE_LOCKING; // for example 8 |
88 |
< |
* try { |
89 |
< |
* do { |
90 |
< |
* if (--retries < 0) |
91 |
< |
* sl.lock(); |
92 |
< |
* seq = sl.awaitAvailability(); |
93 |
< |
* currentX = x; |
94 |
< |
* currentY = y; |
95 |
< |
* } while (sl.getSequence() != seq); |
96 |
< |
* } finally { |
97 |
< |
* if (retries < 0) |
98 |
< |
* sl.unlock(); |
99 |
< |
* } |
100 |
< |
* return Math.sqrt(currentX * currentX + currentY * currentY); |
101 |
< |
* } |
102 |
< |
*}}</pre> |
84 |
> |
* // Uses bounded retries before locking |
85 |
> |
* double distanceFromOriginV2() { |
86 |
> |
* double currentX, currentY; |
87 |
> |
* long seq; |
88 |
> |
* int retries = RETRIES_BEFORE_LOCKING; // for example 8 |
89 |
> |
* try { |
90 |
> |
* do { |
91 |
> |
* if (--retries < 0) |
92 |
> |
* sl.lock(); |
93 |
> |
* seq = sl.awaitAvailability(); |
94 |
> |
* currentX = x; |
95 |
> |
* currentY = y; |
96 |
> |
* } while (sl.getSequence() != seq); |
97 |
> |
* } finally { |
98 |
> |
* if (retries < 0) |
99 |
> |
* sl.unlock(); |
100 |
> |
* } |
101 |
> |
* return Math.sqrt(currentX * currentX + currentY * currentY); |
102 |
> |
* } |
103 |
> |
* }}</pre> |
104 |
|
* |
105 |
|
* @since 1.8 |
106 |
|
* @author Doug Lea |
109 |
|
private static final long serialVersionUID = 7373984872572414699L; |
110 |
|
|
111 |
|
static final class Sync extends AbstractQueuedLongSynchronizer { |
112 |
+ |
static final long serialVersionUID = 2540673546047039555L; |
113 |
+ |
|
114 |
|
/** |
115 |
|
* The number of times to spin in lock() and awaitAvailability(). |
116 |
|
*/ |
162 |
|
|
163 |
|
public final long tryAcquireShared(long unused) { |
164 |
|
return (((getState() & 1L) == 0L) ? 1L : |
165 |
< |
(getExclusiveOwnerThread() == Thread.currentThread()) ? 0L: |
165 |
> |
(getExclusiveOwnerThread() == Thread.currentThread()) ? 0L: |
166 |
|
-1L); |
167 |
|
} |
168 |
|
|
308 |
|
* @param timeout the time to wait for availability |
309 |
|
* @param unit the time unit of the timeout argument |
310 |
|
* @return the current sequence number if the lock is available |
311 |
< |
* upon return from this method. |
311 |
> |
* upon return from this method |
312 |
|
* @throws InterruptedException if the current thread is interrupted |
313 |
|
* @throws TimeoutException if the lock was not available within |
314 |
< |
* the specified waiting time. |
314 |
> |
* the specified waiting time |
315 |
|
* @throws NullPointerException if the time unit is null |
316 |
|
*/ |
317 |
|
public long tryAwaitAvailability(long timeout, TimeUnit unit) |
527 |
|
* @return the number of holds on this lock by the current thread, |
528 |
|
* or zero if this lock is not held by the current thread |
529 |
|
*/ |
530 |
< |
public long getHoldCount() { return sync.getHoldCount(); } |
530 |
> |
public long getHoldCount() { return sync.getHoldCount(); } |
531 |
|
|
532 |
|
/** |
533 |
|
* Queries if this lock is held by the current thread. |