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