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

org.databene.task.runner.MultiThreadedTaskRunner Maven / Gradle / Ivy

Go to download

benerator is a framework for creating realistic and valid high-volume test data, used for testing (unit/integration/load) and showcase setup. Metadata constraints are imported from systems and/or configuration files. Data can imported from and exported to files and systems, anonymized or generated from scratch. Domain packages provide reusable generators for creating domain-specific data as names and addresses internationalizable in language and region. It is strongly customizable with plugins and configuration options.

There is a newer version: 0.9.8
Show newest version
/*
 * (c) Copyright 2010 by Volker Bergmann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, is permitted under the terms of the
 * GNU General Public License (GPL).
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
 * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
 * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package org.databene.task.runner;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicLong;

import org.databene.commons.BeanUtil;
import org.databene.commons.ConfigurationError;
import org.databene.commons.Context;
import org.databene.commons.ErrorHandler;
import org.databene.contiperf.PerformanceTracker;
import org.databene.task.StateTrackingTaskProxy;
import org.databene.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * {@link TaskRunner} implementation that is able to execute a {@link Task} with multiple threads.

* Created: 27.03.2010 14:12:16 * @since 0.6.0 * @author Volker Bergmann */ public class MultiThreadedTaskRunner implements TaskRunner { private static final Logger logger = LoggerFactory.getLogger(MultiThreadedTaskRunner.class); protected Task target; private int threadCount; protected Context context; private ExecutorService executorService; protected ErrorHandler errorHandler; private PerformanceTracker tracker; public MultiThreadedTaskRunner(Task target, int threadCount, Context context, ExecutorService executorService, ErrorHandler errorHandler, PerformanceTracker tracker) { this.target = target; this.threadCount = threadCount; this.context = context; this.executorService = executorService; this.errorHandler = errorHandler; this.tracker = tracker; } public long run(Long maxInvocationCount) { AtomicLong counter = new AtomicLong(); int maxLoopsPerPage = (int)((maxInvocationCount + threadCount - 1) / threadCount); int shorterLoops = (int)(threadCount * maxLoopsPerPage - maxInvocationCount); boolean threadSafe = target.isThreadSafe(); boolean parallelizable = target.isParallelizable(); // create threads for a page CountDownLatch latch = new CountDownLatch(threadCount); for (int threadNo = 0; threadNo < threadCount; threadNo++) { int loopSize = maxLoopsPerPage; if (maxInvocationCount >= 0 && threadNo >= threadCount - shorterLoops) loopSize--; if (loopSize > 0) { Task task = target; if (threadCount > 1 && !threadSafe) { if (parallelizable) { task = BeanUtil.clone(task); } else throw new ConfigurationError("Since the task is not marked as thread-safe," + "it must either be used in a single thread or be parallelizable."); } if (tracker != null) task = ((StateTrackingTaskProxy) task).clone(); TaskRunnable runner = new TaskRunnable(loopSize, counter, latch, !threadSafe); executorService.execute(runner); } else latch.countDown(); } if (logger.isDebugEnabled()) logger.debug("Waiting for end of page on " + target.getTaskName() + "..."); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } if (threadSafe) // TODO v0.7 call pageFinished only if it was actually run in shared mode target.pageFinished(); return counter.get(); } public class TaskRunnable implements Runnable { private CountDownLatch latch; private boolean page; private long requestedInvocationCount; private AtomicLong counter; public TaskRunnable(long requestedInvocationCount, AtomicLong counter, CountDownLatch latch, boolean page) { this.latch = latch; this.page = page; this.requestedInvocationCount = requestedInvocationCount; this.counter = counter; } public void run() { try { long count = SingleThreadedTaskRunner.runWithoutPage(target, requestedInvocationCount, context, errorHandler); counter.addAndGet(count); if (page) target.pageFinished(); } finally { if (latch != null) latch.countDown(); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy