It's not a secret anymore!*
The moose likes Threads and Synchronization and the fly likes Threads, that processed two shared ArrayLists like Queue Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Threads, that processed two shared ArrayLists like Queue" Watch "Threads, that processed two shared ArrayLists like Queue" New topic
Author

Threads, that processed two shared ArrayLists like Queue

Ivan Sidorov
Greenhorn

Joined: Jul 26, 2010
Posts: 3
Hello,

I'm newbie. So, excuse me if my question is stupid. Sorry for my english, too.

I'm trying to build this functionality:

Let's say that we have two ArrayLists:
- keywordsToProcess
- currentKeywords

The idea is that I want to process keywordsToProcess with countless threads.

As keywordsToProcess processing is limited to taking the first element (index 0), then I do things with this element (processing it) and finally I remove this element from keywordsToProcess, because it was processed and should not be included in keywordsToProcess.

There is one condition - I want to choose an element from keywordsToProcess, that is not processing at a current moment of time by other threads. So I use currentKeywords - this is a ArrayList of all keywords that are currently handled by other threads. If the current keyword that is selected is processed by different threads, then I must choose another keyword that is not processing at the moment by other threads.

So, in other words I want to do many threads to work with these ArrayLists (mainly with keywordsToProcess) simultaneously and when there are no keywords left in keywordsToProcess, then the process stops.

Here are examples of classes that I tried to do:

Data.java


RunnableThread.java


Test.java


So when I run the code I got this from console:


So mainly everything works fine, but when one of the threads finish reading the keywordsToProcess (because of size == 0), other thread is still have "old information" for keywordsToProcess, so I think that is the error.
I tried this: http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/essential/concurrency/guardmeth.html - but no success.
I don't know how to fix it. Please, help. Or any other ideas for solving this problem? Thank You!!
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

The basic problem with this code is that you have not made it thread-safe and an arraylist is not intrinsically thread-safe.
There are two basic things that you have to do:

  • Instead of ArrayList use a thread-safe datastructure like an implementation of a BlockingQueue
  • Instead of doing a get(0) and then removing it later, do a poll of the queue


  • Having said the above, i would really recommend you to go through the java concurrency tutorials and any good book on java concurrency like Java Concurrency In practice

    apigee, a better way to API!
    Jim Hoglund
    Ranch Hand

    Joined: Jan 09, 2008
    Posts: 525
    Ivan : Welcome to JavaRanch. You will find a lot of good help here. If you are
    trying to learn more about java, you may want to consider synchronizing the
    ArrayList objects on your own, rather than switching to BlockingQueue. This
    will provide valuable learning.

    Looking at your code, is it true that your input is a list of words that are to be
    processed by a number of threads - one word at a time per thread? For example,
    you could have 25 words to be processed by 6 threads. Or you could start with
    138 words that are to be processed by 205 threads.

    Jim ... ...


    BEE MBA PMP SCJP-6
    Ivan Sidorov
    Greenhorn

    Joined: Jul 26, 2010
    Posts: 3
    Nitesh Kant
    I'll take a look for BlockingQueue. But I still not sure what the problem is. So I'll read more docs.

    Jim Hoglund
    You mean that all of the methods of ArrayList, that I'm using must be synchronized?

    For example the metod arrayListObj.add("keyword") must be look like this:

    For the second part: Yes, the input is a list of words, that must be processed by multiple threads. So one thread process one word, but at given moment of time many threads process their word (not just one).
    For example total words 2000. Threads that process that list: 50. Or something like that.
    So this is the reason, that processData() method is _not_ synchronized, because I want multiple words be processed at some point of time (in above example this is number of threads - 50).

    Thank you for your reply guys!
    Jim Hoglund
    Ranch Hand

    Joined: Jan 09, 2008
    Posts: 525
    Ivan : If I understand your requirements, a single list of words to be processed by
    multiple threads, one word at a time per thread, it seems that your approach may be
    overly complex. Java has some cool tools to easily solve this kind of problem. Are you
    open to changing your approach? Is this an exercise to learn about threads? If so,
    I would be interested in helping further.

    Jim ... ...
    Ivan Sidorov
    Greenhorn

    Joined: Jul 26, 2010
    Posts: 3
    Jim: Yes, I'm open to changing my approach, if there are other ways to do it. So, what is your idea/solution?
    Jim Hoglund
    Ranch Hand

    Joined: Jan 09, 2008
    Posts: 525
    Ivan : Here is code that uses 27 threads; two "Producer" threads that load a single queue object
    and 25 "Consumer" threads that remove the queue entries, one at a time. I suggest that you get
    the code running and then ask questions. Jim ... ...
     
    wood burning stoves
     
    subject: Threads, that processed two shared ArrayLists like Queue