255 *
256 * @param thread the unstarted thread
257 * @return the thread, started
258 * @throws IllegalStateException if this flock is shutdown or closed
259 * @throws IllegalThreadStateException if the given thread was already started
260 * @throws WrongThreadException if the current thread is not the owner or a thread
261 * contained in the flock
262 * @throws StructureViolationException if the current scoped value bindings are
263 * not the same as when the flock was created
264 */
265 public Thread start(Thread thread) {
266 ensureOwnerOrContainsThread();
267 JLA.start(thread, container);
268 return thread;
269 }
270
271 /**
272 * Shutdown this flock so that no new threads can be started, existing threads
273 * in the flock will continue to run. This method is a no-op if the flock is
274 * already shutdown or closed.
275 *
276 * <p> This method may only be invoked by the flock owner or threads {@linkplain
277 * #containsThread(Thread) contained} in the flock.
278 *
279 * @throws WrongThreadException if the current thread is not the owner or a thread
280 * contained in the flock
281 */
282 public void shutdown() {
283 ensureOwnerOrContainsThread();
284 if (!shutdown) {
285 shutdown = true;
286 }
287 }
288
289 /**
290 * Wait for all threads in the flock to finish executing their tasks. This method
291 * waits until all threads finish, the {@link #wakeup() wakeup} method is invoked,
292 * or the current thread is interrupted.
293 *
294 * <p> This method may only be invoked by the flock owner. The method trivially
295 * returns true when the flock is closed.
296 *
297 * <p> This method clears the effect of any previous invocations of the
298 * {@code wakeup} method.
299 *
300 * @return true if there are no threads in the flock, false if wakeup was invoked
301 * and there are unfinished threads
302 * @throws InterruptedException if interrupted while waiting
303 * @throws WrongThreadException if invoked by a thread that is not the owner
353 throw new InterruptedException();
354 remainingNanos = nanos - (System.nanoTime() - startNanos);
355 }
356
357 boolean done = (threadCount == 0);
358 if (!done && remainingNanos <= 0 && !permit) {
359 throw new TimeoutException();
360 } else {
361 clearPermit();
362 return done;
363 }
364 }
365
366 /**
367 * Causes the call to {@link #awaitAll()} or {@link #awaitAll(Duration)} by the
368 * {@linkplain #owner() owner} to return immediately.
369 *
370 * <p> If the owner is blocked in {@code awaitAll} then it will return immediately.
371 * If the owner is not blocked in {@code awaitAll} then its next call to wait
372 * will return immediately. The method does nothing when the flock is closed.
373 *
374 * @throws WrongThreadException if the current thread is not the owner or a thread
375 * contained in the flock
376 */
377 public void wakeup() {
378 ensureOwnerOrContainsThread();
379 if (!getAndSetPermit(true) && Thread.currentThread() != owner()) {
380 LockSupport.unpark(owner());
381 }
382 }
383
384 /**
385 * Closes this flock. This method first shuts down the flock to prevent
386 * new threads from starting. It then waits for the threads in the flock
387 * to finish executing their tasks. In other words, this method blocks until
388 * all threads in the flock finish.
389 *
390 * <p> This method may only be invoked by the flock owner.
391 *
392 * <p> If interrupted then this method continues to wait until all threads
393 * finish, before completing with the interrupt status set.
394 *
395 * <p> A ThreadFlock is intended to be used in a <em>structured manner</em>. If
396 * this method is called to close a flock before nested flocks are closed then it
397 * closes the nested flocks (in the reverse order that they were created in),
398 * closes this flock, and then throws {@code StructureViolationException}.
|
255 *
256 * @param thread the unstarted thread
257 * @return the thread, started
258 * @throws IllegalStateException if this flock is shutdown or closed
259 * @throws IllegalThreadStateException if the given thread was already started
260 * @throws WrongThreadException if the current thread is not the owner or a thread
261 * contained in the flock
262 * @throws StructureViolationException if the current scoped value bindings are
263 * not the same as when the flock was created
264 */
265 public Thread start(Thread thread) {
266 ensureOwnerOrContainsThread();
267 JLA.start(thread, container);
268 return thread;
269 }
270
271 /**
272 * Shutdown this flock so that no new threads can be started, existing threads
273 * in the flock will continue to run. This method is a no-op if the flock is
274 * already shutdown or closed.
275 */
276 public void shutdown() {
277 if (!shutdown) {
278 shutdown = true;
279 }
280 }
281
282 /**
283 * Wait for all threads in the flock to finish executing their tasks. This method
284 * waits until all threads finish, the {@link #wakeup() wakeup} method is invoked,
285 * or the current thread is interrupted.
286 *
287 * <p> This method may only be invoked by the flock owner. The method trivially
288 * returns true when the flock is closed.
289 *
290 * <p> This method clears the effect of any previous invocations of the
291 * {@code wakeup} method.
292 *
293 * @return true if there are no threads in the flock, false if wakeup was invoked
294 * and there are unfinished threads
295 * @throws InterruptedException if interrupted while waiting
296 * @throws WrongThreadException if invoked by a thread that is not the owner
346 throw new InterruptedException();
347 remainingNanos = nanos - (System.nanoTime() - startNanos);
348 }
349
350 boolean done = (threadCount == 0);
351 if (!done && remainingNanos <= 0 && !permit) {
352 throw new TimeoutException();
353 } else {
354 clearPermit();
355 return done;
356 }
357 }
358
359 /**
360 * Causes the call to {@link #awaitAll()} or {@link #awaitAll(Duration)} by the
361 * {@linkplain #owner() owner} to return immediately.
362 *
363 * <p> If the owner is blocked in {@code awaitAll} then it will return immediately.
364 * If the owner is not blocked in {@code awaitAll} then its next call to wait
365 * will return immediately. The method does nothing when the flock is closed.
366 */
367 public void wakeup() {
368 if (!getAndSetPermit(true) && Thread.currentThread() != owner()) {
369 LockSupport.unpark(owner());
370 }
371 }
372
373 /**
374 * Closes this flock. This method first shuts down the flock to prevent
375 * new threads from starting. It then waits for the threads in the flock
376 * to finish executing their tasks. In other words, this method blocks until
377 * all threads in the flock finish.
378 *
379 * <p> This method may only be invoked by the flock owner.
380 *
381 * <p> If interrupted then this method continues to wait until all threads
382 * finish, before completing with the interrupt status set.
383 *
384 * <p> A ThreadFlock is intended to be used in a <em>structured manner</em>. If
385 * this method is called to close a flock before nested flocks are closed then it
386 * closes the nested flocks (in the reverse order that they were created in),
387 * closes this flock, and then throws {@code StructureViolationException}.
|