How can I write a Junit test for the following function. ParallelExecutor extends ThreadPoolExecutor and the WorkerThread will call latch.countDown() on a value change(listener). WorkerThread is a 3 party class. Please let me know how I can tell the test to decrease the latch.
public static void OpenScreen() throws InterruptedException {
//some job...3 party screen
// creating the ThreadPoolExecutor
final ParallelExecutor executorPool = new ParallelExecutor(10);
final CountDownLatch latch = new CountDownLatch(0);
// start the monitoring thread
final MyMonitorThread monitor = new MyMonitorThread(executorPool, 3);
final Thread monitorThread = new Thread(monitor);
monitorThread.start();
// monitorThread.start();
// submit work to the thread pool
for (int i = 0; i < 10; i++) {
executorPool.execute(new WorkerThread(("cmd" + i), latch));
}
latch.await();
Thread.sleep(30000);
// shut down the pool
executorPool.shutdownNow();
// shut down the monitor thread
monitor.shutdown();
}
So what do you want to test? :-) That the execute methods are called? The counting works? Timeouting works if one of the tasks take too much to execute? All the jobs completed when the openScreen() method returns?
If you want to do unit tests, you can play around with mocks (for that, I'd extract this functionality to a separate class where the dependencies like the pool and monitor are passed/injected for the new class). There you can verify if the methods were called properly.
Related
I want to create a thread pool code in java where task will wait until the function called in task in completed. I have gone through many examples but cannot achieve my goal so far.
public class ThreadController {
public static void main(String args[]) {
ExecutorService service = Executors.newFixedThreadPool(5);
List<String> list = new ArrayList<String>();
list.add("john");
list.add("reck");
list.add("moni");
list.add("sasha");
list.add("pely");
for (int p = 0; p < 100; p++) {
for (int r = 0; r < 5; r++) {
Task task = new Task(list.get(r));
service.submit(task);
}
}
}
}
final class Task implements Runnable {
private String taskSimNo;
public Task(String no) {
this.taskSimNo = no;
}
public void run() {
Initiate.startingInitiate(this.taskSimNo);
}
}
The complete idea of this function is to call a function processing() which is a method of mainMethod class. So i want to run 10 threads in parallel but, 11th task should only start when any of the 10 tasks gets finish executing so I need to implement wait function to let the task complete. Any suggestions please.
Your synchronized block with task.wait() does nothing but blocking the loop since there is at no point a call to the notify method.
So you first of all need to remove that.
Secondly, your processing method does not benefit from any multi-threading, because it is called within the constructor and object creation is done by the main thread.
Solution is to move your processing method down inside the run method.
You correctly assigned a limit to the thread pool allowing 10 concurrent tasks to run.
Note: Order is not ensured! Task 11 might run before task 8 for example.
I have the code sample:
public class ThreadPoolTest {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 100; i++) {
if (test() != 5 * 100) {
throw new RuntimeException("main");
}
}
test();
}
private static long test() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(100);
CountDownLatch countDownLatch = new CountDownLatch(100 * 5);
Set<Thread> threads = Collections.synchronizedSet(new HashSet<>());
AtomicLong atomicLong = new AtomicLong();
for (int i = 0; i < 5 * 100; i++) {
Thread.sleep(100);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
threads.add(Thread.currentThread());
atomicLong.incrementAndGet();
countDownLatch.countDown();
Thread.sleep(1000);
} catch (Exception e) {
System.out.println(e);
}
}
});
}
executorService.shutdown();
countDownLatch.await();
if (threads.size() != 100) {
throw new RuntimeException("test");
}
return atomicLong.get();
}
}
I especially made application to work long.
And I see jvisualVM.
Each time gap threadpool was recreated.
After several minutes I see:
but if I use newCachedThreadPool instead of newFixedThreadPool I see constant picture:
Can you explain this behaviour?
P.S.
Problem was that exception occures in code and second iteration was not started
To answer your question; just look here:
private static long test() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(100);
The JVM creates a new ThreadPool during each run of test(), because you tell it to do so.
In other words: if you intend to re-use the same threadpool, then avoid creating/shutting down your instances all the time.
In that sense, the simple fix is: move the creation of that ExecutorService into your main() method; and pass the service as argument to your test() method.
Edit: regarding your last comment on cached vs. fixed threadpool; you probably want to look into this question.
Because you asked it to, in your code ? :) Try moving the Pool creation code outside the test.
From docs:
newFixedThreadPool
Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.
newCachedThreadPool
Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources. Note that pools with similar properties but different details (for example, timeout parameters) may be created using ThreadPoolExecutor constructors.
I am trying to assign a number for each of MyRunnable submitted to ThreadPoolExecutor but I did not succeed.
My code snippet:
import java.util.concurrent.*;
class SimpleThreadFactory implements ThreadFactory {
String name;
static int threadNo = 0;
public SimpleThreadFactory (String name){
this.name = name;
}
public Thread newThread(Runnable r) {
++threadNo;
System.out.println("thread no:"+threadNo);
return new Thread(r,name+":"+threadNo );
}
public static void main(String args[]){
SimpleThreadFactory factory = new SimpleThreadFactory("Ravindra");
ThreadPoolExecutor executor = new ThreadPoolExecutor(1,5,10,TimeUnit.SECONDS,new ArrayBlockingQueue(100),factory);
for ( int i=0; i < 10; i++){
executor.submit(new MyRunnable());
}
executor.shutdown();
}
}
class MyRunnable implements Runnable {
public void run(){
System.out.println("Runnable:"+Thread.currentThread().getName());
}
}
My expectation:
executor.submit(new MyRunnable()); should call newThread in ThreadFactory for each submit on executor. But in reality, it happened only once.
Output:
thread no:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Runnable:Ravindra:1
Why submit() is not creating new thread for each submitted Runnable task?
How can I assign a sequence number to each of MyRunnable submitted to executor?
Thanks in advance
The problem is the interaction between the CorePoolSize and the queue.
From the Javadoc
"If corePoolSize or more threads are running, the Executor always
prefers queuing a request rather than adding a new thread."
and
"If there are more than corePoolSize but less than maximumPoolSize
threads running, a new thread will be created only if the queue is
full."
So currently, your tasks get queued until there is space in the CorePoolSize (i.e. when your currently executing task finishes), so you never use more than 1 thread, currently.
See ThreadPoolExecutor JavaDoc under Core and maximum pool sizes
When a new task is submitted in method execute(java.lang.Runnable), .... If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.
To get your code to make more threads I changed this bit:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
// Core pool size
5,
// Max pool size
5,
// Resize time
1,
// Resize time units
TimeUnit.MILLISECONDS,
// Queue of runnables - I CHANGED THIS TO 10
new ArrayBlockingQueue(10),
// Factory to use for threads.
factory);
for (int i = 0; i < 100; i++) {
executor.submit(new MyRunnable());
}
Other answers explain why there have not been more than one thread. My proposal on how to achieve what you actually wanted is this:
For a start, count the instances of the runnable, not the threads they are run on: For example like this ->
class MyRunnable implements Runnable{
private static long _mySequenceCounter = 0; // Maybe use an AtomicLong?
private final long mySeqNo;
MyRunnable(){ mySeqNo = ++_mySequenceCounter; }
// Your other stuff here
}
Inside run-method, you could rename the current thread if that is sufficient for your requirement. Or you could just output the runnable id and leave the Threads name. That has the advantage that you will know, which thread was reused for which task ... if that has any value to you.
Remark: Above snippet is only to lay out the idea of how to meet your requirement to identify the task. Of course you could improve it if you need thread-safety (snippet could be problematic if MyRunnables are created on more than 1 thread).
long should give you quite a lot of sequence numbers, but mind that even long will roll over at some point. So you might want to address this if your application runs very long and has a high frequency of new MyRunnables.
Try to add a sleep to your "run" method : here the execution time is probably too short to require many thread...
In my application i have used a custom ThreadPoolExecutor which enables pausing and resuming of the Executor by extending the ThreadPoolExecutor class. Same way I want to have Restart functionality implemented where after the shutdown method of the ExecutorService has been executed. I first tried with creating new instance of the ThreadPoolExecutor and it failed. I found this question and tried the ExecutorCompletionService which resulted the same failure where it didn't executed as intended.
First time when I click the start button in my UI it executes fine and after the completion of the process when I again start, it won't give me the intended result. Instead will give me the same previous result of the first run. What is the best suitable way which I can achieve this task ?
Thanks in advance :)
Following lines will be executed at each button click.
private static int jobs = 10;
ExecutorService executor = new PausableThreadPoolExecutor(num_threads, num_threads, 5000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(jobs));
for (int i = 0; i < jobs; i++) {
Runnable worker = new TaskToDo(jobs);
executor.submit(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {}
System.out.println("Finished all threads");
This is the source I used to have pause/resume implementation.
Maybe a ScheduledThreadPoolExecutor you can restart it ScheduledThreadPoolExecutor
using this the methods can return a ScheduledFuture ScheduledFuture or a Future Future to hold references to the tasks
ScheduledFuture now = null;
ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1);
Runnable runner = new Runnable(){
public void run()
{
rollthedice(); //your method or runnable of choice
}
};
to start and restart something like "theres other methods too"
now = scheduler.scheduleAtFixedRate(runner, 0, 250, TimeUnit.MILLISECONDS);
to cancel or stop
now.cancel(true);
now = null;
I want to run several threads and join them at the end of my main method, so I can know when they have finished and process some info.
I don't want to put my threads in an array and do a join() one by one as join is a blocking method and I stay would waiting in the main thread for some threads still running, while other threads may have already finished, without having a possibility of knowing.
I have thought on the possibility of implementing an observer pattern for my threads: An interface with a update() method, an abstract class extending from thread (or implementing runnable) with set and get methods for the listeners and a class starting all my threads and waiting them to finish.
If my understanding is right, an observer would not block in a specific join() for a thread. Instead it will wait somehow until an update() method is called by a thread to perform an action. In this case, the update() should be called right after the thread finishes.
I'm clueless on how to implement this. I've tried with similar models, but I don't know how to use the observer/listener to wake/block my main thread. I've used this old post as a template: How to know if other threads have finished? but I can't find a way to wake my main method once a thread calls the update() method. There will be only one observer object instantiated for all threads.
Could you think of a way to use an observer pattern to wait for all threads to finish without blocking main with one by one join() calls? Any other suggestion to solve this problem would be greatly appreciated. Thanks in advance.
Java already has an API to do that: a CompletionService.
A service that decouples the production of new asynchronous tasks from the consumption of the results of completed tasks. Producers submit tasks for execution. Consumers take completed tasks and process their results in the order they complete.
I think you don't need an observer pattern. Thread waiting for any results will have to block, otherwise it will finish or loop in infinity. You can use some kind of BlockingQueue - producers will add result of computation to the blocking queue (then finish) and main thread will just receive these results blocking when there's not any result yet..
Good news for you, it's already implemented :) Great mechanism of CompletionService and Executors framework. Try this:
private static final int NTHREADS = 5;
private static final int NTASKS = 100;
private static final ExecutorService exec = Executors.newFixedThreadPool(NTHREADS);
public static void main(String[] args) throws InterruptedException {
final CompletionService<Long> ecs = new ExecutorCompletionService<Long>(exec);
for (final int i = 0; i < NTASKS ; ++i) {
Callable<Long> task = new Callable<Long>() {
#Override
public Long call() throws Exception {
return i;
}
};
ecs.submit(task);
}
for (int i = 0; i < NTASKS; ++i) {
try {
long l = ecs.take().get();
System.out.print(l);
} catch (ExecutionException e) {
e.getCause().printStackTrace();
}
}
exec.shutdownNow();
exec.awaitTermination(50, TimeUnit.MILLISECONDS);
}
Sounds to me like you are looking for something like the Counting Completion Service recently discussed by Dr. Heinz M. Kabutz.