Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/demo/jni/Poller/LinkedQueue.java
32287 views
1
/*
2
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
/*
42
File: SLQ.java
43
Originally: LinkedQueue.java
44
45
Originally written by Doug Lea and released into the public domain.
46
This may be used for any purposes whatsoever without acknowledgment.
47
Thanks for the assistance and support of Sun Microsystems Labs,
48
and everyone contributing, testing, and using this code.
49
50
History:
51
Date Who What
52
11Jun1998 dl Create public version
53
25aug1998 dl added peek
54
10dec1998 dl added isEmpty
55
10jun1999 bc modified for isolated use
56
*/
57
58
// Original was in package EDU.oswego.cs.dl.util.concurrent;
59
60
/**
61
* A linked list based channel implementation,
62
* adapted from the TwoLockQueue class from CPJ.
63
* The algorithm avoids contention between puts
64
* and takes when the queue is not empty.
65
* Normally a put and a take can proceed simultaneously.
66
* (Although it does not allow multiple concurrent puts or takes.)
67
* This class tends to perform more efficently than
68
* other Channel implementations in producer/consumer
69
* applications.
70
* <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
71
**/
72
73
public class LinkedQueue {
74
75
76
/**
77
* Dummy header node of list. The first actual node, if it exists, is always
78
* at head_.next. After each take, the old first node becomes the head.
79
**/
80
protected LinkedNode head_;
81
protected int count_;
82
/**
83
* Helper monitor for managing access to last node, in case it is also first.
84
* last_ and waitingForTake_ ONLY used with synch on appendMonitor_
85
**/
86
protected final Object lastMonitor_ = new Object();
87
88
/**
89
* The last node of list. Put() appends to list, so modifies last_
90
**/
91
protected LinkedNode last_;
92
93
/**
94
* The number of threads waiting for a take.
95
* Notifications are provided in put only if greater than zero.
96
* The bookkeeping is worth it here since in reasonably balanced
97
* usages, the notifications will hardly ever be necessary, so
98
* the call overhead to notify can be eliminated.
99
**/
100
protected int waitingForTake_ = 0;
101
102
public LinkedQueue() {
103
head_ = new LinkedNode(null);
104
last_ = head_;
105
count_ = 0;
106
}
107
108
/** Main mechanics for put/offer **/
109
protected void insert(Object x) {
110
synchronized(lastMonitor_) {
111
LinkedNode p = new LinkedNode(x);
112
last_.next = p;
113
last_ = p;
114
count_++;
115
if (count_ > 1000 && (count_ % 1000 == 0))
116
System.out.println("In Queue : " + count_);
117
if (waitingForTake_ > 0)
118
lastMonitor_.notify();
119
}
120
}
121
122
/** Main mechanics for take/poll **/
123
protected synchronized Object extract() {
124
Object x = null;
125
LinkedNode first = head_.next;
126
if (first != null) {
127
x = first.value;
128
first.value = null;
129
head_ = first;
130
count_ --;
131
}
132
return x;
133
}
134
135
136
public void put(Object x) throws InterruptedException {
137
if (x == null) throw new IllegalArgumentException();
138
if (Thread.interrupted()) throw new InterruptedException();
139
insert(x);
140
}
141
142
public boolean offer(Object x, long msecs) throws InterruptedException {
143
if (x == null) throw new IllegalArgumentException();
144
if (Thread.interrupted()) throw new InterruptedException();
145
insert(x);
146
return true;
147
}
148
149
public Object take() throws InterruptedException {
150
if (Thread.interrupted()) throw new InterruptedException();
151
// try to extract. If fail, then enter wait-based retry loop
152
Object x = extract();
153
if (x != null)
154
return x;
155
else {
156
synchronized(lastMonitor_) {
157
try {
158
++waitingForTake_;
159
for (;;) {
160
x = extract();
161
if (x != null) {
162
--waitingForTake_;
163
return x;
164
}
165
else {
166
lastMonitor_.wait();
167
}
168
}
169
}
170
catch(InterruptedException ex) {
171
--waitingForTake_;
172
lastMonitor_.notify();
173
throw ex;
174
}
175
}
176
}
177
}
178
179
public synchronized Object peek() {
180
LinkedNode first = head_.next;
181
if (first != null)
182
return first.value;
183
else
184
return null;
185
}
186
187
188
public synchronized boolean isEmpty() {
189
return head_.next == null;
190
}
191
192
public Object poll(long msecs) throws InterruptedException {
193
if (Thread.interrupted()) throw new InterruptedException();
194
Object x = extract();
195
if (x != null)
196
return x;
197
else {
198
synchronized(lastMonitor_) {
199
try {
200
long waitTime = msecs;
201
long start = (msecs <= 0)? 0 : System.currentTimeMillis();
202
++waitingForTake_;
203
for (;;) {
204
x = extract();
205
if (x != null || waitTime <= 0) {
206
--waitingForTake_;
207
return x;
208
}
209
else {
210
lastMonitor_.wait(waitTime);
211
waitTime = msecs - (System.currentTimeMillis() - start);
212
}
213
}
214
}
215
catch(InterruptedException ex) {
216
--waitingForTake_;
217
lastMonitor_.notify();
218
throw ex;
219
}
220
}
221
}
222
}
223
224
class LinkedNode {
225
Object value;
226
LinkedNode next = null;
227
LinkedNode(Object x) { value = x; }
228
LinkedNode(Object x, LinkedNode n) { value = x; next = n; }
229
}
230
}
231
232