Link to home
Start Free TrialLog in
Avatar of wsyy
wsyy

asked on

How to use a static instance in multi-threading application

Hi,

I originally had a  multi-threading application, each of the threads creating a list of objects and writing the list to database. This method creates a lot of database IO, thereby slowing down the application.

I now want to create a static list, and have each thread add objects to the list and save the list of objects to database whenever the size of list reaches 5000.

How can I pass through the static list to each of the threads effectively?

I currently define the static list in theIncremental.java which utilizes the Java  ExecutorSerices framework.

as follow:

public static List<DBObject> toMove;


The way to call and use the toMove variable is:

            synchronized (Incremental.toMove) {

                  for (String code : code2erid.keySet()) {
                        DBObject q = new BasicDBObject();
                        q.put("code", code);
                        DBObject o = NeferCollection.getInstance().getCollection()
                                    .findOne(q);
                        o.put("erid", code2erid.get(code));
                        o.removeField("_id");

                        Incremental.toMove.add(o);

                        int size = Incremental.toMove.size();

                        if (size % 1000 == 0 && size > 0) {

                              ProdCollection.getInstance().getCollection()
                                          .insert(Incremental.toMove);

                              Incremental.toMove.clear();

                              System.out.println("Moving " + size + " records...");
                        }

                  }

            }


My question is whether my way is  effective to pass through a static object into each thread.
Avatar of dpearson
dpearson

Each thread can directly access a static member (just like in a single threaded program).

The challenge is to make it access this safely.

I would suggest using:

public static List<DBObject> toMove = new CopyOnWriteArrayList<DBObject>() ;

which creates a list which can be accessed simultaneously by multiple threads without throwing exceptions. If you use just a "normal" list like new ArrayList<DBObject>() you'll get exceptions if one thread reads from the list while another thread is modifying it.

Doug
ASKER CERTIFIED SOLUTION
Avatar of rumi78
rumi78

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of wsyy

ASKER

Hi rumi,

The code does insert records to MongoDB in a batch of 1000.

The reason why to clear the list is to keep only new records in the toMove list. (If not cleared, all the old records would be inserted multiple times.)

The issue is, as you point out, the size checking is performed every loop, which  may explains why this multi-threading code is outperformed by non-multi-threading code.

Surely, that is not what I want :)