How to read all Thread Name, Running on JVM? [duplicate] - java

Is there any way I can get a list of all running threads in the current JVM (including the threads not started by my class)?
Is it also possible to get the Thread and Class objects of all threads in the list?
I want to be able to do this through code.

To get an iterable set:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Performance: 0 ms for 12 threads (Azul JVM 16.0.1, Windows 10, Ryzen 5600X).

Get a handle to the root ThreadGroup, like this:
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) {
rootGroup = parentGroup;
}
Now, call the enumerate() function on the root group repeatedly. The second argument lets you get all threads, recursively:
Thread[] threads = new Thread[rootGroup.activeCount()];
while (rootGroup.enumerate(threads, true ) == threads.length) {
threads = new Thread[threads.length * 2];
}
Note how we call enumerate() repeatedly until the array is large enough to contain all entries.

Yes, take a look at getting a list of threads. Lots of examples on that page.
That's to do it programmatically. If you just want a list on Linux at least you can just use this command:
kill -3 processid
and the VM will do a thread dump to stdout.

You can get a lot of information about threads from the ThreadMXBean.
Call the static ManagementFactory.getThreadMXBean() method to get a reference to the MBean.

Have you taken a look at jconsole?
This will list all threads running for a particular Java process.
You can start jconsole from the JDK bin folder.
You can also get a full stack trace for all threads by hitting Ctrl+Break in Windows or by sending kill pid --QUIT in Linux.

You can try something like this:
Thread.getAllStackTraces().keySet().forEach((t) -> System.out.println(t.getName() + "\nIs Daemon " + t.isDaemon() + "\nIs Alive " + t.isAlive()));
and you can obviously get more thread characteristic if you need.

Apache Commons users can use ThreadUtils. The current implementation uses the walk the thread group approach previously outlined.
for (Thread t : ThreadUtils.getAllThreads()) {
System.out.println(t.getName() + ", " + t.isDaemon());
}

To get a list of threads and their full states using the terminal, you can use the command below:
jstack -l <PID>
Which <PID> is the id of process running on your computer. To get the process id of your java process you can simply run the jps command.
Also, you can analyze your thread dump that produced by jstack in TDAs (Thread Dump Analyzer) such fastthread or spotify thread analyzer tool.

In Groovy you can call private methods
// Get a snapshot of the list of all threads
Thread[] threads = Thread.getThreads()
In Java, you can invoke that method using reflection provided that security manager allows it.

Code snippet to get list of threads started by main thread:
import java.util.Set;
public class ThreadSet {
public static void main(String args[]) throws Exception{
Thread.currentThread().setName("ThreadSet");
for ( int i=0; i< 3; i++){
Thread t = new Thread(new MyThread());
t.setName("MyThread:"+i);
t.start();
}
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for ( Thread t : threadSet){
if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup()){
System.out.println("Thread :"+t+":"+"state:"+t.getState());
}
}
}
}
class MyThread implements Runnable{
public void run(){
try{
Thread.sleep(5000);
}catch(Exception err){
err.printStackTrace();
}
}
}
output:
Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING
Thread :Thread[ThreadSet,5,main]:state:RUNNABLE
If you need all threads including system threads, which have not been started by your program, remove below condition.
if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup())
Now output:
Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING
Thread :Thread[Reference Handler,10,system]:state:WAITING
Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING
Thread :Thread[ThreadSet,5,main]:state:RUNNABLE
Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING
Thread :Thread[Finalizer,8,system]:state:WAITING
Thread :Thread[Signal Dispatcher,9,system]:state:RUNNABLE
Thread :Thread[Attach Listener,5,system]:state:RUNNABLE

In the java console, hit Ctrl-Break. It will list all threads plus some information about the heap. This won't give you access to the objects of course. But it can be very helpful for debugging anyway.

public static void main(String[] args) {
// Walk up all the way to the root thread group
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parent;
while ((parent = rootGroup.getParent()) != null) {
rootGroup = parent;
}
listThreads(rootGroup, "");
}
// List all threads and recursively list all subgroup
public static void listThreads(ThreadGroup group, String indent) {
System.out.println(indent + "Group[" + group.getName() +
":" + group.getClass()+"]");
int nt = group.activeCount();
Thread[] threads = new Thread[nt*2 + 10]; //nt is not accurate
nt = group.enumerate(threads, false);
// List every thread in the group
for (int i=0; i<nt; i++) {
Thread t = threads[i];
System.out.println(indent + " Thread[" + t.getName()
+ ":" + t.getClass() + "]");
}
// Recursively list all subgroups
int ng = group.activeGroupCount();
ThreadGroup[] groups = new ThreadGroup[ng*2 + 10];
ng = group.enumerate(groups, false);
for (int i=0; i<ng; i++) {
listThreads(groups[i], indent + " ");
}
}

You can use getAllThreadIds that Returns all live thread IDs. Some threads included in the returned array may have been terminated when this method returns.
ManagementFactory.getThreadMXBean().getAllThreadIds()

Related

Does Java actually run threads in parallel

I would like to understand that does java actually run multiple threads in parallel in a multi core CPU, or there is context switching between threads and only one thread is active and others are waiting for their turn to run.
In other words, is there a possibility that 2 threads are running in parallel???
Because my Thread.currentThread() does not give me a array of threads, but only one thread which is running.
So what is the truth, does only one thread run at a time while others wait or multiple threads can run in parallel, if yes , then why my Thread.currentThread() method return only 1 thread object.
Edit : .....
I have created 2 classes to count numbers
1 class does it synchronously and the other one divides it into two halves and executes the two halves in 2 threads..(intel i5(4 CPUs), 8GB ram)
the code is as follows :
common class :
class Answer{
long ans = 0L;}
Multi Thread execution :
public class Sheet2 {
public static void main(String[] args) {
final Answer ans1 = new Answer();
final Answer ans2 = new Answer();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for(int i=0;i<=500000; i++) {
ans1.ans = ans1.ans + i;
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for(int i=500001;i<=1000000; i++) {
ans2.ans = ans2.ans + i;
}
}
});
long l1 = System.currentTimeMillis();
try {
t1.start();t2.start();
t1.join();
t2.join();
long l2 = System.currentTimeMillis();
System.out.println("ans :" + (ans1.ans + ans2.ans) +" in "+(l2-l1) +" milliseconds");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Single Thread execution :
public class Sheet3 {
public static void main(String[] args) {
final Answer ans1 = new Answer();
long l1 = System.currentTimeMillis();
for(int i=0;i<=1000000; i++) {
ans1.ans = ans1.ans + i;
}
long l2 = System.currentTimeMillis();
System.out.println("ans :" + (ans1.ans ) +" in "+(l2-l1) +" milliseconds"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
My Single thread execution is faster than my multi threaded execution, I though the context switching was putting a overhead on the execution initially and hence the multithreaded execution output was slower, now I am having muti core CPU (4 CPU), but still single threaded execution is faster in this example..
Can you please explain the scenario here... is it because my other processes are eating up the other cores and hence my threads are not running in parallel and performing time slicing on the CPU ???
Kindly throw some light on this topic.
Thanks in advance.
Cheers.!!!
In short yes it does run on separate threads. You can test it by creating 100 threads and checking in your process explorer it will say 100 threads. Also you can do some computation in each thread and you will see your multicore processor go upto 100% usage.
Thread.currentThread gives you the current thread you are running from.
When you start your program you are running on the "main" thread.
As soon as you start a new thread
new Thread(myRunnable);
any code located in the myRunnable will run on the new thread while your current thread is is still on the main Thread.
If you check out the API http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html it gives allot more detailed description of the thread.
The actual threading mechanism can vary between CPU architectures. But the real problem is that you're misinterpreting the method name. Thread.currentThread() doesn't return the thread executing at the current moment in time; it returns the thread currently executing the method call, that is, itself.
Yes it does. Run any simple infinite loop on more than one threads and you'll see the cpu usage > 100% on a multi-core CPU.
Yes it does run threads concurrently .That is the very purpose of the multithreading concept .you may find the folowing discussion helpful :
Current Thread Method java
Not a complete answer here, just adding to what others already have said:
The Java Language Specification does not require that threads run in parallel, but it allows them to do so. What actually happens in any given Java Virtual Machine depends on how that JVM is implemented.
Any practical JVM will create one "native" (i.e., operating system) thread for each Java thread, and let the operating system take care of scheduling, locking, waiting, notifying,...

Incrementing Thread Name

I have made a function that takes x amount of parameters. Each parameter, represents a file.
I want every single of these files to be assigned a thread, for counting the words of the files as fast as possible. Currently I have done something that seems to work, however I find myself in trouble of checking the threads as they are all just assigned with the name "t"
It would be nice to somehow increment the name of the threads. The first thread would be t1 and would be assigned to the first file and so on.
for (File file : fileList) {
final File f = file;
Thread t = null;
ThreadGroup test = null;
Runnable r = new Runnable() {
public void run() {
Scanner fileScan;
try {
fileScan = new Scanner(f);
}
catch(FileNotFoundException e){
System.out.println("Something went wrong while accessing the file");
return;
}
int words = 0;
while (fileScan.hasNext()) {
words++;
fileScan.next();
}
System.out.println(f.getName() + ": " + words + " words");
System.out.println(Thread.activeCount() + ": ");
}
};
t = new Thread(r);
t.start();
}
The threadcount goes up as it is supposed when checking with Thread.activeCount(), but I have no clue how to ever contact them as I have assigned all with the name t, which makes it hard to make yet another thread that shall wait for their output.
I hope my explaination clearified the problem :/
Edit:
The idea is that I will count the amount of words in different files, every file needs to be assigned a thread for itself to speed it up. Other than that, I want one thread waiting for the output from all the other threads ( meaning I will have to wait for them to finish, hence why I would appriciate accessing the name of the threads ).
At the end that last thread that has been waiting will use the collected data for it's own actions before closing the program down.
In order to for instance wait for the threads to finish, you need to save references to the threads you create. You could for instance do
List<Thread> threads = new ArrayList<>();
and then do threads.add(t); at the end of the loop.
After that you could wait for them to finish by doing
for (Thread t : threads) {
t.join();
}
What's problematic however is that there is no way for you to read the result of the threads you've started.
A much better approach to this is to use an ExecutorService and a ThreadPoolExecutor. This way you can submit Callable<Integer> instead of Runnable, and you'll be able to get the result of the word-count.
Here's an outline to get you started:
ExecutorService service = Executors.newFixedThreadPool(numThreads);
List<Future<Integer>> results = new ArrayList<>();
for (File f : fileList) {
results.add(service.submit(new Callable<Integer>() {
// ...
}));
}
for (Future<Integer> result : results) {
System.out.println("Result: " + result.get());
}

How to print out all the threads and its current status?

Is there a way to print out all the threads and its id, status using code?
For example, I have 5 threads, and I want to enumerate all of them.
You can do as below.
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread thread: threadSet) {
System.out.println(thread.getId());
}
Make sure you read and understand the method Thread.getAllStackTraces() before using them.
Use
Thread.currentThread().getId();
Assign the thread object to a public variable if you need to control the thread from other parts of the program, or print it out directly if you just want to know what's running:
public int myThreadId = 0;
public void run () {
System.out.println("Thread Name: " + Thread.currentThread().getName(); // Printing the thread name
myThreadId = Thread.currentThread().getId(); // Assigning the thread ID to a public variable
}
Read more: How to Get a Reference to a Java Thread | eHow.com http://www.ehow.com/how_6879305_reference-java-thread.html#ixzz2FfEUe3cF
Also
Get a handle to the root ThreadGroup, like this:
ThreadGroup rootGroup = Thread.currentThread( ).getThreadGroup( );
ThreadGroup parentGroup;
while ( ( parentGroup = rootGroup.getParent() ) != null ) {
rootGroup = parentGroup;
}
Now, call the enumerate() function on the root group repeatedly. The second argument lets you get all threads, recursively:
Thread[] threads = new Thread[ rootGroup.activeCount() ];
while ( rootGroup.enumerate( threads, true ) == threads.length ) {
threads = new Thread[ threads.length * 2 ];
}
Note how we call enumerate() repeatedly until the array is large enough to contain all entries.

How to check the number of currently running threads in Java?

I'm looking for a way to see the number of currently running threads
Through Windows first
Programmatically
This will give you the total number of threads in your VM :
int nbThreads = Thread.getAllStackTraces().keySet().size();
Now, if you want all threads currently executing, you can do that :
int nbRunning = 0;
for (Thread t : Thread.getAllStackTraces().keySet()) {
if (t.getState()==Thread.State.RUNNABLE) nbRunning++;
}
The possible states are enumerated here: Thread.State javadoc
If you want to see running threads not programmaticaly but with a Windows tool, you could use Process Explorer.
You can get all the threads and their stack traces running in the JVM uses Thread.getAllStackTraces()
In response to your following comment
In the following piece of code: while(resultSet.next()) {
name=resultSet.getString("hName"); MyRunnable worker = new
MyRunnable(hName); threadExecutor.execute( worker ); } . My thread
pool has size of 10. I need to make sure that my program working
correctly with multi-threadings & want to check how many threads are
running at a certain moment. How can I do this?
to another answer, I suggest that you profile your code with JVisualVM and check if your thread pool is working as it should. The reason behind this suggestion is that then you don't have to bother with all the other housekeeping threads that JVM manages. Besides what you want to do is why tools like JVisualVM are made for.
If you are new to profiling Java programs, JVisualVM lets you see what goes on under the hood while you are running your code. You can see the Heap, GC activity, inspect the threads running/waiting any sample/profile your cpu or memory usage. There are quite a few plugins as well.
From Windows:
There's bound to be a performance counter for the process that can tell you that.
Programmatically:
There's Thread#activeCount:
Returns an estimate of the number of active threads in the current thread's thread group and its subgroups. Recursively iterates over all subgroups in the current thread's thread group.
Or more directly, ThreadGroup#activeCount:
Returns an estimate of the number of active threads in this thread group and its subgroups.
and ThreadGroup#getParent:
Returns the parent of this thread group.
First, if the parent is not null, the checkAccess method of the parent thread group is called with no arguments; this may result in a security exception.
All of which seem to suggest something along the lines of:
int activeThreadTotalEstimate() {
ThreadGroup group;
ThreadGroup parent;
group = Thread.currentThread().getThreadGroup();
while ((parent = group.getParent()) != null) {
group = parent;
}
return group.activeCount();
}
Code snippet:
import java.util.Set;
import java.lang.Thread.State;
public class ActiveThreads {
public static void main(String args[]) throws Exception{
for ( int i=0; i< 5; i++){
Thread t = new Thread(new MyThread());
t.setName("MyThread:"+i);
t.start();
}
int threadCount = 0;
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for ( Thread t : threadSet){
if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup() &&
t.getState() == Thread.State.RUNNABLE){
System.out.println("Thread :"+t+":"+"state:"+t.getState());
++threadCount;
}
}
System.out.println("Thread count started by Main thread:"+threadCount);
}
}
class MyThread implements Runnable{
public void run(){
try{
Thread.sleep(2000);
}catch(Exception err){
err.printStackTrace();
}
}
}
output:
Thread :Thread[main,5,main]:state:RUNNABLE
Thread count started by Main thread:1
Explanation:
Thread.getAllStackTraces().keySet() provides you list of all Threads, which have been started by both Program and System. In absence of ThreadeGroup condition, you will get System thread count if they are active.
Reference Handler, Signal Dispatcher,Attach Listener and Finalizer

wait until all threads finish their work in java

I'm writing an application that has 5 threads that get some information from web simultaneously and fill 5 different fields in a buffer class.
I need to validate buffer data and store it in a database when all threads finished their job.
How can I do this (get alerted when all threads finished their work) ?
The approach I take is to use an ExecutorService to manage pools of threads.
ExecutorService es = Executors.newCachedThreadPool();
for(int i=0;i<5;i++)
es.execute(new Runnable() { /* your task */ });
es.shutdown();
boolean finished = es.awaitTermination(1, TimeUnit.MINUTES);
// all tasks have finished or the time has been reached.
You can join to the threads. The join blocks until the thread completes.
for (Thread thread : threads) {
thread.join();
}
Note that join throws an InterruptedException. You'll have to decide what to do if that happens (e.g. try to cancel the other threads to prevent unnecessary work being done).
Have a look at various solutions.
join() API has been introduced in early versions of Java. Some good alternatives are available with this concurrent package since the JDK 1.5 release.
ExecutorService#invokeAll()
Executes the given tasks, returning a list of Futures holding their status and results when everything is completed.
Refer to this related SE question for code example:
How to use invokeAll() to let all thread pool do their task?
CountDownLatch
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.
Refer to this question for usage of CountDownLatch
How to wait for a thread that spawns it's own thread?
ForkJoinPool or newWorkStealingPool() in Executors
Iterate through all Future objects created after submitting to ExecutorService
Wait/block the Thread Main until some other threads complete their work.
As #Ravindra babu said it can be achieved in various ways, but showing with examples.
java.lang.Thread.join() Since:1.0
public static void joiningThreads() throws InterruptedException {
Thread t1 = new Thread( new LatchTask(1, null), "T1" );
Thread t2 = new Thread( new LatchTask(7, null), "T2" );
Thread t3 = new Thread( new LatchTask(5, null), "T3" );
Thread t4 = new Thread( new LatchTask(2, null), "T4" );
// Start all the threads
t1.start();
t2.start();
t3.start();
t4.start();
// Wait till all threads completes
t1.join();
t2.join();
t3.join();
t4.join();
}
java.util.concurrent.CountDownLatch Since:1.5
.countDown() « Decrements the count of the latch group.
.await() « The await methods block until the current count reaches zero.
If you created latchGroupCount = 4 then countDown() should be called 4 times to make count 0. So, that await() will release the blocking threads.
public static void latchThreads() throws InterruptedException {
int latchGroupCount = 4;
CountDownLatch latch = new CountDownLatch(latchGroupCount);
Thread t1 = new Thread( new LatchTask(1, latch), "T1" );
Thread t2 = new Thread( new LatchTask(7, latch), "T2" );
Thread t3 = new Thread( new LatchTask(5, latch), "T3" );
Thread t4 = new Thread( new LatchTask(2, latch), "T4" );
t1.start();
t2.start();
t3.start();
t4.start();
//latch.countDown();
latch.await(); // block until latchGroupCount is 0.
}
Example code of Threaded class LatchTask. To test the approach use joiningThreads();
and latchThreads(); from main method.
class LatchTask extends Thread {
CountDownLatch latch;
int iterations = 10;
public LatchTask(int iterations, CountDownLatch latch) {
this.iterations = iterations;
this.latch = latch;
}
#Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " : Started Task...");
for (int i = 0; i < iterations; i++) {
System.out.println(threadName + " : " + i);
MainThread_Wait_TillWorkerThreadsComplete.sleep(1);
}
System.out.println(threadName + " : Completed Task");
// countDown() « Decrements the count of the latch group.
if(latch != null)
latch.countDown();
}
}
CyclicBarriers A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
CyclicBarrier barrier = new CyclicBarrier(3);
barrier.await();
For example refer this Concurrent_ParallelNotifyies class.
Executer framework: we can use ExecutorService to create a thread pool, and tracks the progress of the asynchronous tasks with Future.
submit(Runnable), submit(Callable) which return Future Object. By using future.get() function we can block the main thread till the working threads completes its work.
invokeAll(...) - returns a list of Future objects via which you can obtain the results of the executions of each Callable.
Find example of using Interfaces Runnable, Callable with Executor framework.
#See also
Find out thread is still alive?
Apart from Thread.join() suggested by others, java 5 introduced the executor framework. There you don't work with Thread objects. Instead, you submit your Callable or Runnable objects to an executor. There's a special executor that is meant to execute multiple tasks and return their results out of order. That's the ExecutorCompletionService:
ExecutorCompletionService executor;
for (..) {
executor.submit(Executors.callable(yourRunnable));
}
Then you can repeatedly call take() until there are no more Future<?> objects to return, which means all of them are completed.
Another thing that may be relevant, depending on your scenario is CyclicBarrier.
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
Another possibility is the CountDownLatch object, which is useful for simple situations : since you know in advance the number of threads, you initialize it with the relevant count, and pass the reference of the object to each thread.
Upon completion of its task, each thread calls CountDownLatch.countDown() which decrements the internal counter. The main thread, after starting all others, should do the CountDownLatch.await() blocking call. It will be released as soon as the internal counter has reached 0.
Pay attention that with this object, an InterruptedException can be thrown as well.
You do
for (Thread t : new Thread[] { th1, th2, th3, th4, th5 })
t.join()
After this for loop, you can be sure all threads have finished their jobs.
Store the Thread-objects into some collection (like a List or a Set), then loop through the collection once the threads are started and call join() on the Threads.
You can use Threadf#join method for this purpose.
Although not relevant to OP's problem, if you are interested in synchronization (more precisely, a rendez-vous) with exactly one thread, you may use an Exchanger
In my case, I needed to pause the parent thread until the child thread did something, e.g. completed its initialization. A CountDownLatch also works well.
I created a small helper method to wait for a few Threads to finish:
public static void waitForThreadsToFinish(Thread... threads) {
try {
for (Thread thread : threads) {
thread.join();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
An executor service can be used to manage multiple threads including status and completion. See http://programmingexamples.wikidot.com/executorservice
try this, will work.
Thread[] threads = new Thread[10];
List<Thread> allThreads = new ArrayList<Thread>();
for(Thread thread : threads){
if(null != thread){
if(thread.isAlive()){
allThreads.add(thread);
}
}
}
while(!allThreads.isEmpty()){
Iterator<Thread> ite = allThreads.iterator();
while(ite.hasNext()){
Thread thread = ite.next();
if(!thread.isAlive()){
ite.remove();
}
}
}
I had a similar problem and ended up using Java 8 parallelStream.
requestList.parallelStream().forEach(req -> makeRequest(req));
It's super simple and readable.
Behind the scenes it is using default JVM’s fork join pool which means that it will wait for all the threads to finish before continuing. For my case it was a neat solution, because it was the only parallelStream in my application. If you have more than one parallelStream running simultaneously, please read the link below.
More information about parallel streams here.
The existing answers said could join() each thread.
But there are several ways to get the thread array / list:
Add the Thread into a list on creation.
Use ThreadGroup to manage the threads.
Following code will use the ThreadGruop approach. It create a group first, then when create each thread specify the group in constructor, later could get the thread array via ThreadGroup.enumerate()
Code
SyncBlockLearn.java
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* synchronized block - learn,
*
* #author eric
* #date Apr 20, 2015 1:37:11 PM
*/
public class SyncBlockLearn {
private static final int TD_COUNT = 5; // thread count
private static final int ROUND_PER_THREAD = 100; // round for each thread,
private static final long INC_DELAY = 10; // delay of each increase,
// sync block test,
#Test
public void syncBlockTest() throws InterruptedException {
Counter ct = new Counter();
ThreadGroup tg = new ThreadGroup("runner");
for (int i = 0; i < TD_COUNT; i++) {
new Thread(tg, ct, "t-" + i).start();
}
Thread[] tArr = new Thread[TD_COUNT];
tg.enumerate(tArr); // get threads,
// wait all runner to finish,
for (Thread t : tArr) {
t.join();
}
System.out.printf("\nfinal count: %d\n", ct.getCount());
Assert.assertEquals(ct.getCount(), TD_COUNT * ROUND_PER_THREAD);
}
static class Counter implements Runnable {
private final Object lkOn = new Object(); // the object to lock on,
private int count = 0;
#Override
public void run() {
System.out.printf("[%s] begin\n", Thread.currentThread().getName());
for (int i = 0; i < ROUND_PER_THREAD; i++) {
synchronized (lkOn) {
System.out.printf("[%s] [%d] inc to: %d\n", Thread.currentThread().getName(), i, ++count);
}
try {
Thread.sleep(INC_DELAY); // wait a while,
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("[%s] end\n", Thread.currentThread().getName());
}
public int getCount() {
return count;
}
}
}
The main thread will wait for all threads in the group to finish.
I had similar situation , where i had to wait till all child threads complete its execution then only i could get the status result for each of them .. hence i needed to wait till all child thread completed.
below is my code where i did multi-threading using
public static void main(String[] args) {
List<RunnerPojo> testList = ExcelObject.getTestStepsList();//.parallelStream().collect(Collectors.toList());
int threadCount = ConfigFileReader.getInstance().readConfig().getParallelThreadCount();
System.out.println("Thread count is : ========= " + threadCount); // 5
ExecutorService threadExecutor = new DriverScript().threadExecutor(testList, threadCount);
boolean isProcessCompleted = waitUntilCondition(() -> threadExecutor.isTerminated()); // Here i used waitUntil condition
if (isProcessCompleted) {
testList.forEach(x -> {
System.out.println("Test Name: " + x.getTestCaseId());
System.out.println("Test Status : " + x.getStatus());
System.out.println("======= Test Steps ===== ");
x.getTestStepsList().forEach(y -> {
System.out.println("Step Name: " + y.getDescription());
System.out.println("Test caseId : " + y.getTestCaseId());
System.out.println("Step Status: " + y.getResult());
System.out.println("\n ============ ==========");
});
});
}
Below method is for distribution of list with parallel proccessing
// This method will split my list and run in a parallel process with mutliple threads
private ExecutorService threadExecutor(List<RunnerPojo> testList, int threadSize) {
ExecutorService exec = Executors.newFixedThreadPool(threadSize);
testList.forEach(tests -> {
exec.submit(() -> {
driverScript(tests);
});
});
exec.shutdown();
return exec;
}
This is my wait until method: here you can wait till your condition satisfies within do while loop . in my case i waited for some max timeout .
this will keep checking until your threadExecutor.isTerminated() is true with polling period of 5 sec.
static boolean waitUntilCondition(Supplier<Boolean> function) {
Double timer = 0.0;
Double maxTimeOut = 20.0;
boolean isFound;
do {
isFound = function.get();
if (isFound) {
break;
} else {
try {
Thread.sleep(5000); // Sleeping for 5 sec (main thread will sleep for 5 sec)
} catch (InterruptedException e) {
e.printStackTrace();
}
timer++;
System.out.println("Waiting for condition to be true .. waited .." + timer * 5 + " sec.");
}
} while (timer < maxTimeOut + 1.0);
return isFound;
}
Use this in your main thread: while(!executor.isTerminated());
Put this line of code after starting all the threads from executor service. This will only start the main thread after all the threads started by executors are finished. Make sure to call executor.shutdown(); before the above loop.

Categories