All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.publicobject.misc.util.concurrent.JobQueue Maven / Gradle / Ivy

/* Glazed Lists                                                      (c) 2005 */
/* http://publicobject.com/glazedlists/                      publicobject.com,*/
/*                                                     O'Dell Engineering Ltd.*/
/*                                                          StarLight Systems */
package com.publicobject.misc.util.concurrent;

import java.util.List;
import java.util.ArrayList;

/**
 * A simple task queue for writing multithreaded tests.
 *
 * 

This has special logic to maintain the thread interrupted state between * tasks. If the thread was interrupted at the end of one task, it will stay * interrupted at the start of the next task. * * @author Jesse Wilson */ public class JobQueue implements Runnable { /** the tasks to invoke, in order of invocation */ private List jobs = new ArrayList(); @Override public void run() { boolean interrupted = false; while(true) { // find a job to run, if any Job job = null; synchronized(this) { if(!jobs.isEmpty()) { job = jobs.remove(0); } else { try { wait(); } catch(InterruptedException e) { // interrupt the next execution interrupted = true; } continue; } } // run the job try { if(interrupted) { Thread.currentThread().interrupt(); } job.runnable.run(); interrupted = Thread.interrupted(); } catch(Throwable t) { synchronized(job) { job.thrown = t; } } finally { synchronized(job) { job.done = true; job.notify(); } } } } /** * Invoke the specified job and return immediately. */ public Job invokeLater(Runnable runnable) { // queue the job for execution Job job = new Job(runnable); synchronized(this) { jobs.add(job); notify(); } return job; } /** * Invoke the specified job on the other thread and wait for it to complete. */ public void invokeAndWait(Runnable runnable) { // queue the job for execution Job job = new Job(runnable); synchronized(this) { jobs.add(job); notify(); } // wait for the job to complete synchronized(job) { while(!job.done) { try { job.wait(); } catch(InterruptedException e) { throw new RuntimeException(e); } } } // if the job threw anything, throw that job.rethrowIfNecessary(); } public void flush() { // flush the queue invokeAndWait(new NoOpRunnable()); } private class NoOpRunnable implements Runnable { @Override public void run() { // do nothing } } /** * A task and its result. */ public static class Job { private final Runnable runnable; private boolean done = false; private Throwable thrown = null; public Job(Runnable runnable) { this.runnable = runnable; } public void rethrowIfNecessary() { if(thrown == null) return; if(thrown instanceof RuntimeException) throw (RuntimeException)thrown; if(thrown instanceof Error) throw (Error)thrown; throw new IllegalStateException("Unexpected throwable " + thrown.getClass()); } public Throwable getThrown() { return thrown; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy