Hi all,

Do any of you have an experience using the Java API in a multithreaded 
context?  I'm trying to spread some processing across multiple threads to try 
and speed things up, but am getting the exact opposite result.  In this 
instance, I'm trying to quickly delete a certain number of entries from a form, 
and I'm finding that if I do it in a single thread, it deletes approximately 50 
records/second.  However, if I do it with two threads, the overall rate drops 
to less than 25 records/second - not per thread, overall.  That means that the 
time that it takes to actually delete a single record is taking on average four 
times longer when using 2 threads instead of 1.  I get the same results whether 
I use the same ARServerUser object in each thread or if I create new ones for 
each thread.

Have any of you seen this or does anyone have any idea what might be going on 
here?

I've copied the relevant source code below for your reference.  Thanks for any 
help.

Thanks,
Lyle Taylor


//=========================================================================
// This class is just used to encapsulate the list of entries to be deleted
// and synchronizes access to the list of entries shared among all the threads.
//=========================================================================
import java.util.List;
import java.util.Iterator;
import com.bmc.arsys.api.*;

public class EntriesToDelete {
      String mForm;
      List<Entry> mEntries;
      int mReportFrequency;
      int mReturnedCount = 0;
      Iterator<Entry> mIter;
      
      public EntriesToDelete(String inForm, List<Entry> inEntries, int 
inReportFrequency) {
            mForm = inForm;
            mEntries = inEntries;
            mReportFrequency = inReportFrequency;
            mIter = mEntries.iterator();
      }
      
      public String Form() {
            return mForm;
      }
      
      public Entry NextEntry() {
            synchronized(this) {
                  ++mReturnedCount;
                  if ( mReportFrequency != 0 && mReturnedCount % 
mReportFrequency == 0 ) {
                        System.out.println("Deleted " + mReturnedCount + " of " 
+ mEntries.size());
                  }
                  if ( mIter.hasNext() ) {
                        return mIter.next();
                  } else {
                        return null;
                  }
            }
      }
}

//=========================================================================
// This class does the actual work.  An instance is created for each thread to 
be run.
//=========================================================================

import com.bmc.arsys.api.*;

public class DeleteEntryWorker implements Runnable {
      ARServerUser mSrv;
      EntriesToDelete mEntries;
      
      public DeleteEntryWorker(String inServer, String inUser, String 
inPassword, int inPort, EntriesToDelete inEntries) {
            mSrv = new ARServerUser(inUser, inPassword, null, inServer, inPort);
            mEntries = inEntries;
      }
      
      public void run() {
            Entry e;            
            while ( (e = mEntries.NextEntry()) != null ) {
                try {
                    mSrv.deleteEntry(mEntries.Form(), e.getEntryId(), 0);       
      
                } catch (ARException ex) {}
            }
      }
}


//=========================================================================
// The following two methods perform the query to determine what to delete and 
then spawns
// the threads that do the work.  They belong to the application's class.
//=========================================================================

      public static void CleanNotifierLogs(ARServerUser inServer) throws 
ARException, InterruptedException {
            String form = "NTE:Notifier Log";

            int fields[] = {1};
            OutputInteger nMatches = new OutputInteger();

            // only 500 entries are being pulled back for testing
            List<Entry> entries = inServer.getListEntryObjects(form, null, 0, 
500, null, fields, false, nMatches);
            
            if ( nMatches.intValue() > 0 ) {
                  DeleteEntries(inServer, form, entries, 2, 50);
            }
      }
      
      public static void DeleteEntries(ARServerUser inServer, String inForm, 
List<Entry> inEntries, int inNumThreads, int inReportFrequency) throws 
ARException, InterruptedException {
            EntriesToDelete entries = new EntriesToDelete(inForm, inEntries, 
inReportFrequency);

            // Two methods have been tried, just to see if there would be any 
difference
//          ExecutorService pool = Executors.newFixedThreadPool(inNumThreads);
//
//          for (int i = 0; i < inNumThreads; ++i) {
//                pool.execute(new DeleteEntryWorker(inServer.getServer(), 
inServer.getUser(), inServer.getPassword(), inServer.getPort(), entries));
//          }
//          pool.shutdown();

            Thread threads[] = new Thread[inNumThreads];
            for (int i = 0; i < inNumThreads; ++i) {
                  threads[i] = Executors.defaultThreadFactory().newThread(new 
DeleteEntryWorker(inServer.getServer(), inServer.getUser(), 
inServer.getPassword(), inServer.getPort(), entries));
                  threads[i].start();
            }
            
            for (int i = 0; i < inNumThreads; ++i) {
                  threads[i].join();
            }
      }
 


 NOTICE: This email message is for the sole use of the intended recipient(s) 
and may contain confidential and privileged information. Any unauthorized 
review, use, disclosure or distribution is prohibited. If you are not the 
intended recipient, please contact the sender by reply email and destroy all 
copies of the original message.

_______________________________________________________________________________
UNSUBSCRIBE or access ARSlist Archives at www.arslist.org
Platinum Sponsor:[email protected] ARSlist: "Where the Answers Are"

Reply via email to