Solved

Analyzing thread profiling

Posted on 2013-06-21
10
352 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
ID: 39266040
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
ID: 39266098
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
ID: 39266198
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
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 35

Accepted Solution

by:
mccarl earned 350 total points
ID: 39267702
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
ID: 39275422
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
 
LVL 16

Assisted Solution

by:Valeri
Valeri earned 150 total points
ID: 39277214
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
ID: 39282850
>>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
ID: 39289206
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
ID: 39318790
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
ID: 39319653
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

830 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