Solved

Analyzing thread profiling

Posted on 2013-06-21
10
340 Views
Last Modified: 2013-07-18
hi guys

I have 11 threads(ThreadTaskExecutor) running on a 2CPU (12 cores)

Attached is the screenshot of my threads.
Any idea what the 4 states mean (at the bottom right of the image)
Running
Sleeping
Wait
Monitor

From the screenshot it looks like most of the threads are in
Monitor state.
How can i improve the performance (increase / decrease number of threads ?)

Any help will be greatly appreciated

thanks
Threads.bmp
0
Comment
Question by:royjayd
  • 4
  • 3
  • 3
10 Comments
 
LVL 16

Expert Comment

by:Valeri
Comment Utility
is it screenshot from JProfiler?
It looks like only one thread is dedicated for your concurent thread pool.
If you have 12 cores it's the right decision to have 12 working threads, but it's difficult for me to understand why the picture is like this without the code.
read this article to understand how to utilize all of the CPU cores. It's short and very good:
http://embarcaderos.net/2011/01/23/parallel-processing-and-multi-core-utilization-with-java/

btw state 'monitor' is BLOCKED state, in which the thread is waiting to obtain a lock on an object, but it's not able to, because some other thread already hold this lock.
0
 
LVL 35

Expert Comment

by:mccarl
Comment Utility
If you follow the diagram through you will see that 90% of the time, only 1 of your 11 threads are actually running at any point in time, and (as you said) the rest of the time they are in Monitor state. In case you don't know, Monitor state means that the thread is blocked waiting to get a hold of a lock (or monitor, hence the state's name).

So either your code uses an explicit Lock object or implicitly via "synchronized" methods it is manipulating locks, and in a way that will never be good for multithreaded execution, ie. no matter how many threads you allocate, more or less, it won't significantly change the performance. You need to look at the code that is being run to see why there is so much "lock contention".

Can you post the code?
0
 

Author Comment

by:royjayd
Comment Utility
thanks
Its the screenshot from VisualVM profiler

Regarding the code:
My code is a single java process which executes a batch task.
The task is to select data from one table and insert it into another table.
Here is the snapshot of code

SPRING_CONFIG.xml

<tasklet transaction-manager="transactionManager"
task-executor="threadTaskExecutor" throttle-limit="10">
<chunk reader="itemReader" 
writer="itemWriter"
commit-interval="5000"  />
</tasklet>

<beans:bean id="threadTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<beans:bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
</beans:bean>

Open in new window



itemReader - SELECT COL1 as value1,COL2 as value2 from TABLE1
itemWriter - INSERT INTO TABLE2(COL1,COL2) values (:value1,:value2)

TABLE1 has 1 million rows
so the above process writes/inserts 1 million rows from TABLE1 to TABLE2
and this task is distributed among 11 threads.
 
I have a ProcessMain class with a main() which invokes the
above tasklet in SPRING_CONFIG.xml

public class ProcessMain{
public static void main(String args[]) {

ThreadPoolTaskExecutor threadPoolTaskExecutor = null;
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(SPRING_CONFIG);
try {
threadPoolTaskExecutor = (ThreadPoolTaskExecutor) applicationContext.getBean("threadTaskExecutor");
threadPoolTaskExecutor.setCorePoolSize(11); //configure 11 threads
threadPoolTaskExecutor.setMaxPoolSize(12);
} catch (Exception e) {
logger.error("exception ..woohoo", e);
	}

//invoke <tasklet> xml
}
}

Open in new window


So as you can see there is no synchronization being used.
Any idea how i can improve the performance.
The whole process takes more than 30 minutes,

thanks
0
 
LVL 35

Accepted Solution

by:
mccarl earned 350 total points
Comment Utility
So as you can see there is no synchronization being used.
Ahh, that's not necessarily true. YOU may not have implemented any synchronization, but that doesn't mean the code libraries that you are using haven't.

Refer to Spring Batch doco, section 7.1   http://static.springsource.org/spring-batch/reference/html/scalability.html

In particular the last couple of paragraphs of that section. It is all very helpful, but this following sentence is the most pertinent...
In particular most of the off-the-shelf readers and writers from Spring Batch are not designed for multi-threaded use
And one of the reasons for these issues.. think about you above SELECT statement. If that is executed by 11 threads in parallel, then each 1 of those threads are going to read every record from TABLE1.

To be able to do any parallel processing of this type of task, and have any hope of improving performance, then YOU need to devise a way of partitioning the work of reading (and subsequently writing) the 1 million records. Whether there is some column in that table that would allow you to easily divide up the work? And then I would recommend reading a lot more of that Chapter 7 of the Spring Batch doco that I linked, to work out the best way of implementing it.

We don't have enough details about what you are trying to do, and the data in the DB to really help you much more on how to improve performance.
0
 

Author Comment

by:royjayd
Comment Utility
little consufed now..if the readers and writers are not designed for multithreaded use
then why is there a option to use the ThreadpoolTaskExecutor
something like

i am doing something like

 <step id="copyDataStep" next="nextTask">
<tasklet transaction-manager="transactionManager"
task-executor="threadpooltaskexecutor" throttle-limit="10">

<beans:bean id="threadpooltaskexecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property corepoolsize = "10" >
</beans:bean>

why is there a 'task-executor' option, do  you know?

thanks.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 16

Assisted Solution

by:Valeri
Valeri earned 150 total points
Comment Utility
Wow, I didn't know that this is the case.
If all of this is related to DB operation, then you don't need thread pool at java at all.
In your case every thread is responsible to move all of the data from table1 to table2, it means that at the end the job is completed 11 times (by every thread).
I'm agree with the previous post, ThreadPoolTaskExecutor's should be used if you have a criteria to assign a smaler part of the task to each thread, so when all of the threads complete, it will mean that the whole task is completed.
for example if you have to calculate sum of 100 elements in fastest way, and you have 10 threads, the first should sum 1-10, the second 11-20...
But it's not applicable in your case.
Every DB has mechanism to do such as operations in parallel mode /in fastest way/.
In my opinion you have to ask this question in DB topic. If your DB is Oracle, go to ORACLE topic and ask: "How to move 1 million records from one table to another is fastest way"
0
 

Author Comment

by:royjayd
Comment Utility
>>In your case every thread is responsible to move all of the data from table1 to table2, it means that at the end the job is completed 11 times (by every thread).

that is not the case for me. so what you mean is since every thread is moving data from table1 to table2 there would be 11 million rows (one million by each thread)
but that is not the case, i see only one million in table2.
so in thoery what you said makes sense but practically that is not happening.


>>for example if you have to calculate sum of 100 elements in fastest way, and you have 10 threads, the first should sum 1-10, the second 11-20
how would you go about doing this ? I mean how would you assign
thread1 to sum 1-10
thread2 to sum 11-20
and so on..

Can you post some code ?

thx.
0
 
LVL 16

Expert Comment

by:Valeri
Comment Utility
Partitioning of the task is up to developer. Especially for partitioning of array you can check this article:

http://www.vogella.com/articles/JavaAlgorithmsPartitionCollection/article.html

it's a generic class that partitions a List to subLists.
0
 

Author Comment

by:royjayd
Comment Utility
hi Valeri and mccarl

I looked into the code and i take back my statement.
""So as you can see there is no synchronization being used"

Actually I am reading the data synchronously...so revisiting my code i have
<tasklet transaction-manager="transactionManager"
task-executor="threadTaskExecutor" throttle-limit="10">
<chunk reader="itemReader"
writer="itemWriter"
commit-interval="5000"  />
</tasklet>
..

<beans:bean id="itemReader" parent="synchItemReader">
<beans:property name="delegate" ref="stageReader" />
</beans:bean>

<beans:bean id="synchItemReader"       class="com.xmon.batch.SynchItemReader" abstract="true" />

package com.xmon.batch;

import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;

public class SynchItemReader<T> implements ItemReader<T>, ItemStream {

	private ItemReader<T> delegate;
	
		@Override
	public synchronized T read() throws Exception, UnexpectedInputException,
			ParseException, NonTransientResourceException {
		return delegate.read();
	}

	public ItemReader<T> getDelegate() {
		return delegate;
	}

	public void setDelegate(ItemReader<T> delegate) {
		this.delegate = delegate;
	}

}

Open in new window


As you can see the read() which reads the data from the table is synchronized
so now i unserstand why so many threads are in monitor state.

Any sugesions on how i can improve the performance.
thanks.
0
 
LVL 35

Expert Comment

by:mccarl
Comment Utility
Any sugesions on how i can improve the performance.
As we said earlier, probably the only way to increase performance is... for you to find some property of your data that will allow you to partition this process among the threads, ie. say you have an id column in this table with values from 1 - 1000000 for the 1 million rows that it stores, then you would partition the work so that the first thread does "select * from TABLE where id >= 1 and id <= 100000" and the second thread does "select * from TABLE where id >= 100001 and id <= 200000", etc, etc.

The link that I posted above mentions that Spring-Batch comes with an example (parallelJob) that sounds pretty much like what you are trying to do, so that might be a starting point.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
matchUp  challenge 9 71
sumHeights  challenge 17 59
bitbucket vs gitbucket 3 28
get weblogic logged in user in java 2 39
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now