limit maximum threads executing at time in java - java

Trying to figure out how threading in Java works, i just want to limit runnable threads executing by putting them all to array and then check in loop if some of them finished and pop them out, to have possibility to spawn a new thread, got exception in this code:
public class testThread implements Runnable {
public void run () {
try {
Thread.sleep(1000);
} catch(InterruptedException e){}
System.out.println("This is the test thread");
}
public static void main (String args[]) {
int max_threads = 5;
Thread worker;
ArrayList<Thread> all_workers = new ArrayList<Thread>(max_threads );
for (int i =0; i<50; i++) {
if (all_workers.size()<max_threads){
worker = new Thread (new testThread());
all_workers.add(worker);
worker.start();
} else{
System.out.println("i ran all");
while(all_workers.size()>=max_threads){
try{
System.out.println("Waiting for some to finish");
int counter = 0;
for (Thread wrk: all_workers){
if (!wrk.isAlive()){
all_workers.remove(counter);
}
counter ++ ;
}
Thread.sleep(500);
} catch (InterruptedException e){
System.out.println("Catched unhandled ");
}
}
}
}
for(Thread wrk: all_workers){
try {
wrk.join();
} catch (InterruptedException e) {
}
}
}
}
exception i got when i run it:
anybody#anymachine ~/java $ java testThread
i ran all
Waiting for some to finish
Waiting for some to finish
This is the test thread
This is the test thread
This is the test thread
This is the test thread
This is the test thread
Waiting for some to finish
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at testThread.main(testThread.java:39)
thank you for any help, if there is a good tutorial i would be much appriciated for link.
PS. if there is any debugger in java like pdb in python please let me know.
thank you!

You should have a look at the higher level threading utilities like ExecutorService and ThreadPools.
You should never terminate a thread manually and I suggest to avoid manual thread creation/management in general.
If you want to wait for a number of threads finishing, you may want to use a CountDownLatch.
Here is an example.

Exception in thread "main" java.util.ConcurrentModificationException
You are getting this because you are removing from an ArrayList while you are iterating across it. This is not allowed.
for (Thread wrk : all_workers) {
if (!wrk.isAlive()) {
// ERROR, you can't change the collection while you are in a for loop
all_workers.remove(counter);
}
...
If you need to remove from a list you are walking across, you should use the iterator.remove() instead:
Iterator<Thread> iterator = all_workers.iterator();
while (interator.hasNext()) {
Thread wrk = interator.next();
if (!wrk.isAlive()) {
// this is allowed because you are using the iterator directly
iterator.remove();
}
}
A better solution to your specific situation is to use the ExecutorService code. What you do then is to create a fixed thread pool and submit your jobs to it:
// create a thread pool with 5 worker threads
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// define your jobs somehow
for (int i = 0; i < 50; i++) {
threadPool.submit(new testThread());
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
// then wait for it to complete
threadPool.awaitTermination(Long.MAX_LONG, TimeUnit.MILLISECONDS);

First, why do you need to limit the number of running threads? Note, computer cannot simultaneously run more threads than it has processors anyway.
The main drawback of your solution is Thread.sleep(500). It causes unnecessary latency.
The right solution is to use a java.util.Executor with desired number of threads. Then you simply call executor.execute(new testThread()) instead of new Thread (new testThread()).start().

Change the below line
ArrayList<Thread> all_workers = new ArrayList<Thread>(max_threads);
To
Set<Thread> all_workers = Collections.newSetFromMap(new ConcurrentHashMap<Thread,Boolean>())

Related

Awaiting pool to finish threads

StopWatch sw = new StopWatch();
sw.start();
ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
for (int i = 0; i < MYTHREADS; i++) {
Runnable worker = new SingleConnectionRunnable();
executor.execute(worker);
}
sw.stop();
System.out.println("total time"+sw.toString());
sw.reset();
sw.start();
for (int i = 0; i < MYTHREADS; i++) {
Runnable worker2 = new PooledConnectionRunnable();
executor.execute(worker2);
}
executor.shutdown();
executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
while (!executor.isTerminated()) {
}
sw.stop();
System.out.println("total time"+sw.toString());
I am trying to run some perf tests on the code above. I am trying to use the same executor on different Runnable and measure the time. But it doesn't quite work. the first "total time" is not correct which is in milliseconds.
I want to print the elapsed time on the first loop then print the second loop. Not sure how I can wait executor to finish the first one then restart the executor.
What is the correct way to get this done?
First, awaitTermination will block until all tasks terminate. Is there any particular reason that you use a while loop check after waiting potentially 70 years?
Anyways, to answer your question, in order to wait for the first run to finish, you should use a CountDownLatch to signal completion of each thread and await for them in the main thread until they finish. You can also use a CyclicBarrier to await until all your threads are ready to go before starting timing, like so:
...
CountDownLatch latch = new CountDownLatch(MYTHREADS);
CyclicBarrier cb = new CyclicBarrier(MYTHREADS, new Runnable() {
#Override public void run() {
sw.start();
}
});
for (...) {
Runnable worker = ...
executor.execute(new Runnable() {
#Override public void run() {
try {
cb.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
worker.run();
latch.countDown();
}
});
}
latch.await();
sw.stop();
...
I moved the sw.start() to the beginning of the for-loop to avoid measuring object allocation overhead to setup (probably won't be measured anyways since its in ms).
You can also reset the two concurrency classes to run an indefinite number of times.
What you are doing now is:
Start the stopwatch
Start a few threads
Read the stopwatch
You are not waiting for them to finish like you do with the second loop.
This is what you can do to fix this.
Make a callback method in the SingleConnectionRunnable.
This method will be called at the last point of this runnable (when you terminate it) and caught by the class that starts the loop (which is not method in the question but that is fine).
In this callback method you keep track of how many times it is called.
When it is called MYTHREAD amount of times you print the stopwatch time.
Now you know how long it will take until all started threads are finished.

Java Threading: Is using interrupt() within run() acceptable to stop a thread when it is finished completing its task?

I have setup a Java Thread class which preforms a particular task of creating a new Process and running it along with various other things.
In the parent class which invokes the Thread I have setup a loop
while(!thread.isActive()) {
...
}
I wanted to know if it is best practices / acceptable to update the run() in the Thread class to issue a interrupt()
run() {
callTask();
interrupt();
}
Update
I could then create a boolean finished field on the Thread and change that to true once the callTask() is completed and have the parent look for
Thread:
run() {
callTask();
finished = true;
}
Parent:
// Start the threads for each Device
for (DeviceRunner deviceRunner : deviceRunners) {
deviceRunner.start();
}
boolean doneProcessingDevices = false;
while (!doneProcessingDevices) {
Set<DeviceRunner> deviceRunnersToRemove = new HashSet<DeviceRunner>();
for (DeviceRunner deviceRunner : deviceRunners) {
if (deviceRunner.isFinishedRunning()) { // check to see if the thread is finished
deviceRunnersToRemove.add(deviceRunner);
}
}
// remove the device runners which are no longer active
deviceRunners.removeAll(deviceRunnersToRemove);
if (deviceRunners.isEmpty()) {
doneProcessingDevices = true;
}
Thread.sleep(1000);
}
Thank you
Just to clarify: you don't have to stop threads manually. When run() completes, the native thread will die and the Thread object will be garbage collected.
If you want your parent to wait until all tasks completed, you can use a CountDownLatch. Initialize the latch with the number of tasks that have to be done. Every time a task finishes, let him invoke countDown(). In the meantime, your parent blocks on await():
Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.
This MWE demonstrates the basic idea:
int numberOfTasks = 3;
CountDownLatch latch = new CountDownLatch(numberOfTasks);
while (numberOfTasks-- > 0) {
new Thread(() -> {
try {
// Do stuff.
System.out.println("Done.");
} finally {
latch.countDown();
}
}).start();
}
try {
latch.await();
System.out.println("All tasks finished.");
} catch (InterruptedException e) { /* NOP */ }
You won't see All tasks finished. before each task has printed Done..
I believe what you are really looking for is Thread.join method. Copying from Oracle tutorial
The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing, t.join()
causes the current thread to pause execution until t's thread terminates

Handling the Hanging Tasks [duplicate]

This question already has answers here:
ExecutorService that interrupts tasks after a timeout
(11 answers)
Closed 7 years ago.
This is just an example to explain my problem...
I am using ExecutorService with 20 active threads and 75K max queued items...
In my case, a normal task should not take more than 10 seconds, if it takes more time that means there's some problem with the task.
If all the threads are hung due to problematic tasks my RejectionHandler would restart the entire service.
I have two questions here:
I do not like the idea of restarting the service, instead if there's
way to detect hanging thread and we could just restart that hung
thread that would be great. I have gone through couple of articles to handle hung threads with ThreadManager but have not found anything
with ExecutorService.
I am very much fascinated about the Executors.newCachedThredPool()
because on peak days we are heavily loaded with incoming tasks, and
on other days they are very few. Any suggestions would be greatly
appreciated.
public class HangingThreadTest {
// ExecutorService executorService = Executors.newCachedThreadPool()
private static ExecutorService executorService = new ThreadPoolExecutor(10,
20, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(75000));
public static void main(String... arg0) {
for (int i = 0; i < 50000; i++) {
executorService.submit(new Task());
}
}
}
/**
* Task to be completed
*/
class Task implements Runnable {
private static int count = 0;
#Override
public void run() {
count++;
if (count%5 == 0) {
try {
System.out.println("Hanging Thread task that needs to be reprocessed: "
+ Thread.currentThread().getName()+" count: "+count);
Thread.sleep(11000);
} catch (InterruptedException e) {
// Do something
}
}
else{
System.out.println("Normal Thread: "
+ Thread.currentThread().getName()+" count: "+count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//Do something
}
}
}
}
There is no build-in mechanism in Executors framework that would help terminate a thread if it has been running for more than a threshold value.
But we can achieve this with some extra code as below:
Get the Future object returned by the executorService.submit(...);.
Future future = executorService.submit(new Task());
Call the get method on this future object to and make it wait only for threshold interval for task completion. Below, an example that is waits for only 2 secs.
try {
f.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
f.cancel(true);
} catch (Exception e) {}
The above code waits for 2 seconds for task completion it throws a TimeoutException if it doesn't get completed during that time. Subsequently we can call cancel method on the future object. This results in setting the interrupt flag in the thread that is executing the task.
Now the final change is, in the Task class code we need to check at necessary points (application dependent), whether the interrupt flag has been set to true using isInterrupted() method of Thread class. If interrupted==true, we can do the necessary clean up and return from the run method immediately. The critical piece here is to identify the necessary points in your Task class where you want to check for this interrupted flag.
This makes the thread available for processing next task.
You may have a look at this article, it was very helpful for me before when I was facing the same problem : Java Hanging Thread Detection

Facing Issue in Join method in thread

I have a doubt that I am creating few threads inside a loop and it will call the run method that I had implemented . I have doubt that though I have written t.join without completing its run method main thread is moving forward and executing later steps. How to stop this ?
for(int j=1;j<=iteration;j++){
Thread t=null;
System.out.println("Starting Iteration-"+j);
for(int i=1;i<=totalNumberOfUsers;i++) {
t=new Thread(new CasLoadTest());
t.setName("User"+i);
t.start();
Thread.sleep((long) (delayPeriod*1000));
}
t.join();
for(Map.Entry<String,Long> map:latencyMap.entrySet()){
System.out.println(map.getKey()+"-"+map.getValue());
}
System.out.println("Iteration"+j+"-->Max:"+Collections.max(latencyMap.values()));
System.out.println("Iteration"+j+"-->Min:"+Collections.min(latencyMap.values()));
double temp=(double)(lastUserLoggedIn-firstUserLoggedIn)/1000;
System.out.println("Iteration"+j+"-->Total Number of Users Logged In (Users\\Sec)--"+totalNumberOfUsers/temp);
latencyMap.clear();
threadCount = totalNumberOfUsers;
count = 0;
Thread.sleep(30000);
}
Collect all Threads that you have created in a list. Then you can wait for all to exit their operation before going on with your main method.
ArrayList<Thread> allThreads = new ArrayList<>(); // create a list of all Threads
for(int i=1;i<=totalNumberOfUsers;i++) {
t=new Thread(new CasLoadTest());
allThreads.add(t); // add new Thread to list
...
}
...
// wait for all Threads to end before executing next code
for(Thread thread : allThreads)
thread.join();

How can we save a thread for next task after its execution in java (Implementation of Thread pooling )

I need to ask about how thread pooling is implemented for having constant number of thread executing each time when there is task submission happened . (In Executor to avoid each time thread creation and deletion overhead)
executor.submit(Runnable)
Lets say we create some threads in the start and when task come we assign task to them(Thread) using any Queue impl . But after completing it s task how could a thread return to its pool again when as per the lifecycle of thread says that
"After execution of its run method it goes into TERMINATED state and can't be used again"
I am not understood how thread pool works for having constant number of threads for execution of any task to its queue .
It would be great if anyone could provide me an example of thread reuse after its completion of task .
!!Thanks in advance .!!
"After execution of its run method it goes into TERMINATED state and can't be used again"
It doesn't finish its run() Instead it has a loop which runs the run() of the tasks you provide it.
Simplifying the thread pool pattern dramatically you have code which looks like this.
final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();
public void submit(Runnable runs) {
tasks.add(runs);
}
volatile boolean running = true;
// running in each thread in the pool
class RunsRunnable implement Runnable {
public void run() {
while(running) {
Runnable runs = tasks.take();
try {
runs.run();
} catch(Throwable t) {
// handles t
}
}
}
}
In this example, you can see that while the run() of each task completes, the run() of the thread itself does not until the pool is shutdown.
Usually what happens when we use thread pool , Its inside Run method it is forced to run iteratively. Until there are tasks available in the Queue.
in the below example pool.removeFromQueue() will run iteratively.
public class MyThread<V> extends Thread {
private MyThreadPool<V> pool;
private boolean active = true;
public boolean isActive() {
return active;
}
public void setPool(MyThreadPool<V> p) {
pool = p;
}
/**
* Checks if there are any unfinished tasks left. if there are , then runs
* the task and call back with output on resultListner Waits if there are no
* tasks available to run If shutDown is called on MyThreadPool, all waiting
* threads will exit and all running threads will exit after finishing the
* task
*/
#Override
public void run() {
ResultListener<V> result = pool.getResultListener();
Callable<V> task;
while (true) {
task = pool.removeFromQueue();
if (task != null) {
try {
V output = task.call();
result.finish(output);
} catch (Exception e) {
result.error(e);
}
} else {
if (!isActive())
break;
else {
synchronized (pool.getWaitLock()) {
try {
pool.getWaitLock().wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
void shutdown() {
active = false;
}
Need to design your thread pool
public MyThreadPool(int size, ResultListener<V> myResultListener) {
tasks = new LinkedList<Callable<V>>();
threads = new LinkedList<MyThread<V>>();
shutDown = false;
resultListener = myResultListener;
for (int i = 0; i < size; i++) {
MyThread<V> myThread = new MyThread<V>();
myThread.setPool(this);
threads.add(myThread);
myThread.start();
}
}
You can take a look here: http://www.ibm.com/developerworks/library/j-jtp0730/index.html for more details and an implementation example. The threads in the pool will wait if the queue is empty and will each start consome messages once they are notified that the queue has some elements.
ExecutorService executor = Executors.newFixedThreadPool(2);
- The above statement created a ThreadPool with fixed size of 2.
executor.execute(new Worker());
- The above statement takes an instance of the class Worker which has implemented Runnable Interface.
- Now here the Executors is an intermediate object, executing the task. Which manages the Thread Objects.
- By executing the above statement the run() method will be executed, and once the run() method completes, the thread doesNot go into dead state but moves back into the pool, waiting to have another work assigned to it, so it can once again move into Runnable state and then to running, all this is handled by Executors .
executor.shutdown();
- The above statement will shutdown the Executors itself, gracefully handling the shutdown of all the threads managed by it..shutdown() on that central object, which in turn could terminate each of the registered executors.
////////// Edited Part//////////////////////
- First of all Runnable has a run() method which canNot return anything, and run() method canNot throw a checked exception, So Callable was introduced in Java 5, which is of Parametric type , and has a method called call(), and it is capable of returning , and throwing Checked exceptions.
Now see this Example:
Thread t = new Thread(new Worker());
t.run();
t.start();
- t.run() is just a simple call to run() method, this won't span a thread of execution.
- t.start() whereas prepares for the things important for the initialization of the thread of execution, and then calls the run() method of the Runnable, and then assign the Task to the newly formed thread of execution, and returns quickly....
Threads in Java becomes a necessity when using Swing and AWT. Mainly the GUI component.
I am totally agree with Peter but want add steps related to ExecutorService execution flow, for clear understanding.
If you create pool (fixed size pool) of threads it does not means that threads were created.
If you submit and/or execute new Task (Runnuble or Callable) new thread will be created JUTS if count of created threads < size of pool
Created threads not returning to pool, threads can wait for new value in blocking queue, this point we can call RETURNING TO POOL
All threads from pool execs like Peter described above.

Categories

Resources