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

org.anadix.utils.MultithreadedAnalyzer Maven / Gradle / Ivy

package org.anadix.utils;

import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

import org.anadix.Anadix;
import org.anadix.Analyzer;
import org.anadix.Report;
import org.anadix.Source;

public class MultithreadedAnalyzer {
	private ExecutorService exec;
	private final Analyzer analyzer;
	private final Map> results;
	private final AtomicInteger count = new AtomicInteger(1);

	public MultithreadedAnalyzer() throws InstantiationException {
		this(Anadix.newAnalyzer(), Runtime.getRuntime().availableProcessors());
	}

	public MultithreadedAnalyzer(Analyzer analyzer) {
		this(analyzer, Runtime.getRuntime().availableProcessors());
	}

	public MultithreadedAnalyzer(Analyzer analyzer, int threads) {
		if (analyzer == null) {
			throw new NullPointerException("analyzer can't be null");
		}
		if (threads < 1) {
			throw new IllegalArgumentException("thread count must be greater than or equal to 1");
		}

		this.analyzer = analyzer;
		exec = Executors.newFixedThreadPool(threads);
		results = new ConcurrentHashMap>();
	}

	public int submittAnalysis(Source source) {
		int id = count.getAndIncrement();
		results.put(id, exec.submit(new AnalysisTask(analyzer, source)));

		return id;
	}

	public Report getResult(int id) throws ResultException {
		return getResult(id, true);
	}

	public Report getResult(int id, boolean block) throws ResultException {
		Future future = results.get(id);
		try {
			if (future != null) {
				if (block) {
					return future.get();
				} else {
					try {
						return future.get(1, TimeUnit.MILLISECONDS);
					} catch (TimeoutException ex) {
						// ok
					}
				}
			}
		} catch (InterruptedException ex) {
			throw new ResultException("Interrupted", ex);
		} catch (ExecutionException ex) {
			throw new ResultException("Error during execution", ex.getCause());
		}

		return null;
	}

	public boolean dispose() {
		return dispose(30, TimeUnit.SECONDS);
	}

	public boolean dispose(long timeout, TimeUnit unit) {
		exec.shutdown();
		try {
			if (!exec.awaitTermination(timeout, unit)) {
				exec.shutdownNow();
			} else {
				return true;
			}
		} catch (InterruptedException ex) {
			ex.printStackTrace();
		}
		return false;
	}

	private static class AnalysisTask implements Callable {
		private final Analyzer a;
		private final Source s;

		public AnalysisTask(Analyzer a, Source s) {
			this.a = a;
			this.s = s;
		}

		public Report call() throws Exception {
			return a.analyze(s);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy