File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes Refactor code into mutlithreaded Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Refactor code into mutlithreaded" Watch "Refactor code into mutlithreaded" New topic
Author

Refactor code into mutlithreaded

Maciej Kowalski
Greenhorn

Joined: Apr 22, 2013
Posts: 6
Hi

In terms of multi-threading i am noob. I have written some programs which uses Java thread but nothing special.

Current code is single-threaded. It reads data from file, generate random numbers and check if that numbers belong to given inteval.



here goes the input file:



I don't expect for anyone to write code for me.

But I don't know how to make this methods multi-threaded



Any help (links, info etc) would be great.

Best.
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2277
    
  28

Your problem is a good candidate for java.util.concurrent.ThreadPoolExecutor. The ThreadPoolExecutor contains a thread pool and a queue. You create instances of class that implement Callable and add it to the queue. All the threads wait for callable objects to appear on the queue. When an object appears, one thread pops it out, executes it and then goes back to waiting. You can set up a executor to have a pool of 5-10 threads, and put 100 objects in the queue, and they will execute them one by one. When you submit a task to the queue, the execute returns a Future object. The Future object encapsulates the result of the task. It provides methods that allow your main thread to check if the task is done and also to get the result of the task

So, in your case, you need to decide how you want to break up your processing into tasks. In both methods you have 2 for loops. Do you want to have a task for each iteration of outer loop, or have a task per iteration of the inner loop. More tasks mean smaller tasks, and that means you can have better progress tracking (if you need in the future). However, more tasks also means that you will have to do some sort of processing after tasks are complete to merge the results. so depending on how much work it is to merge the results, you might to have bigger tasks.

I would split generateRandomNumbers to have a task per iteration of inner loop. Since, all you do is add the result to a list. I would split checkIntervals to have a task per iteration of outerloop, since the inner loop counts the number of hits.
Maciej Kowalski
Greenhorn

Joined: Apr 22, 2013
Posts: 6
Jayesh A Lalwani wrote:Your problem is a good candidate for java.util.concurrent.ThreadPoolExecutor. The ThreadPoolExecutor contains a thread pool and a queue. You create instances of class that implement Callable and add it to the queue. All the threads wait for callable objects to appear on the queue. When an object appears, one thread pops it out, executes it and then goes back to waiting. You can set up a executor to have a pool of 5-10 threads, and put 100 objects in the queue, and they will execute them one by one. When you submit a task to the queue, the execute returns a Future object. The Future object encapsulates the result of the task. It provides methods that allow your main thread to check if the task is done and also to get the result of the task

So, in your case, you need to decide how you want to break up your processing into tasks. In both methods you have 2 for loops. Do you want to have a task for each iteration of outer loop, or have a task per iteration of the inner loop. More tasks mean smaller tasks, and that means you can have better progress tracking (if you need in the future). However, more tasks also means that you will have to do some sort of processing after tasks are complete to merge the results. so depending on how much work it is to merge the results, you might to have bigger tasks.

I would split generateRandomNumbers to have a task per iteration of inner loop. Since, all you do is add the result to a list. I would split checkIntervals to have a task per iteration of outerloop, since the inner loop counts the number of hits.


Wooooow! This forum is better than StackOverflow.

Thanks for so detailed explanation.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18546
    
  40



A few points to consider (assuming that you are considering threading to go faster)...

1. It takes time to start and coordinate threads. You will be paying a time cost for this, so short tasks are not a good candidate for threading... meaning that the multithreaded version can take longer to run than the single threaded version.

2. It takes time to synchronize between threads -- so consider distributing work as coarse as possible. The optimal case is to have each thread get all its sub-tasks once. Of course, if the sub-tasks have different execution times, then you will need to get more finer.... however, if you get too fine, then, again, the multithreaded version can take longer to run than the single threaded version.

3. If order matters, then it will be much harder. If order matters, then you will need synchronization between threads. In the extreme case, it simply isn't possible to go multithreaded. In the other cases, this synchronization takes time (and the threads will be effectively single threaded while this is happening)... and again, the multithreaded version can take longer to run than the single threaded version.

4. Threads is only useful when there are resources to run the threads. Lots of threads running on lots of cores is the best case. If you are running on a single core processor box, then you have lots of threads trying to share the one available core ... and again, the multithreaded version can take longer to run than the single threaded version.


Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Henry Wong wrote:
4. Threads is only useful when there are resources to run the threads. Lots of threads running on lots of cores is the best case. If you are running on a single core processor box, then you have lots of threads trying to share the one available core ... and again, the multithreaded version can take longer to run than the single threaded version.


That's an important point, excellently stated. (Emphasis added by me.) I think a lot of beginners don't realize this.

It's like you have 10 tasks written down on a piece of paper. You can hand that paper to one minion and tell him to go off and do those tasks. But if you have 10 minions, you can tear that paper into 10 pieces (one for each task--like starting 10 threads) and hand each piece to one minion, and they can go off and each can do one task. Since all 10 tasks are now being executed at the same time, by 10 different minions, they get done faster. But if you have just one minion, tearing the paper into 10 separate pieces (threads) doesn't help, because he can still only do one tasks at a time.

Another possible breakdown of resources and threads to use them is one thread to read the data from the file or network and stick it into a work queue, and then one or more threads (depending on how many cores you have) to read from that queue and process the data. If you're reading from multiple input sources, other than multiple files on the same physical disk, you might also benefit from multiple reader threads rather than just one.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Refactor code into mutlithreaded
 
Similar Threads
Have a chess board, need help assigning values so GUI can update
Probability Question
How to handle rows/columns in arrays
Problems with writing image on server side
constructors and calling methods