1

I feel REALLY dumb even asking this question and probably is dumb to ask because I assume the answer is "it should never do that", but I am very stuck in this current issue i'm in so i want to ask anyways.

I have an Array Class I created...

public class Search_Results_Item {
    private String SortSearchSite;
    private String SortSearchLocation;
    private String SortTitle;
    private String SortLinkURL;
    private String SortImageSRC;
    private String SortPrice;
    private String SortDescription;
    private String SortLocation;
    private String SortDateTime;
    private String SortTrueDateTime;
    private String SortOriginalURL;


    public Search_Results_Item(String SortSearchSite, String SortSearchLocation, String SortTitle, String SortLinkURL, String SortImageSRC,
            String SortPrice, String SortDescription, String SortLocation, String SortDateTime, String SortTrueDateTime, String SortOriginalURL) {
        this.SortSearchSite = SortSearchSite;
        this.SortSearchLocation = SortSearchLocation;
        this.SortTitle = SortTitle;
        this.SortLinkURL = SortLinkURL;
        this.SortImageSRC = SortImageSRC;
        this.SortPrice = SortPrice;
        this.SortDescription = SortDescription;
        this.SortLocation = SortLocation;
        this.SortDateTime = SortDateTime;
        this.SortTrueDateTime = SortTrueDateTime;
        this.SortOriginalURL = SortOriginalURL;

    }

I call it in my method by doing...

 private ArrayList<Search_Results_Item> SearchResultsRow = new ArrayList<Search_Results_Item>();

I add items to this from 2 different threads that are started at the same time using..

SearchResultsRow.add(new Search_Results_Item(sSite, sLocation, SortTitle, SortLinkURL, SortImageSRC, SortPrice, SortDescription, SortLocation,
                            SortDateTime, EPOCHDATETIME, sBaseURL));

I then have a runnable that is constantly running and its doing this...

            getWriteDB();
            Sql_Database_Globals.SQL_DATABASE.beginTransaction();

            while (SearchResultsRow.size() > 0) {
                int theMax = SearchResultsRow.size() - 1;
                SQLCOUNT++;
                Search_Results_Item ITEM = SearchResultsRow.get(theMax);
                SearchResultsRow.remove(ITEM);
                try {
                    if (ITEM != null) {

                        SQLiteStatement statement = Sql_Database_Globals.SQL_DATABASE
                                .compileStatement("INSERT INTO TEMPSORT (SortSearchSite, SortSearchLocation, SortTitle, SortLinkURL, SortImageSRC, SortPrice, SortDescription, SortLocation, SortDateTime, SortTrueDateTime, SortOriginalURL) VALUES (?,?,?,?,?,?,?,?,?,?,?)");
                        statement.clearBindings();
                        statement.bindString(1, ITEM.getSortSearchSite());
                        statement.bindString(2, ITEM.getSortSearchLocation());
                        statement.bindString(3, ITEM.getSortTitle());
                        statement.bindString(4, ITEM.getSortLinkURL());
                        statement.bindString(5, ITEM.getSortImageSRC());
                        statement.bindString(6, ITEM.getSortPrice());
                        statement.bindString(7, ITEM.getSortDescription());
                        statement.bindString(8, ITEM.getSortLocation());
                        statement.bindString(9, ITEM.getSortDateTime());
                        statement.bindString(10, ITEM.getSortTrueDateTime());
                        statement.bindString(11, ITEM.getSortOriginalURL());


                        statement.executeInsert();
                    } else {
                        Log.d("EXCEPTION", "----------->NULL");
                    }
                } catch(Exception e1){
                    // catch all the exceptions
                    Log.d("SQLEXCEPTION", "SQL - > " + e1.getMessage());

                }

            }

            Sql_Database_Globals.SQL_DATABASE.setTransactionSuccessful();
            Sql_Database_Globals.SQL_DATABASE.endTransaction();
            SQLDB.close();

Now for some MIRACULOUS reason. Sometimes there are a few items that were suppose to be added to the SearchResults (and a before and after count confirms it was added) won't actually get looked at and attempted to be inserted into the SQLDatabase (which is what the SQLCOUNT++ is). Sometimes its off by only 1 record, sometimes 3. 90%+ of the time it does all the records.

I can't for the life of me begin to understand what I'm missing.

eqiz
  • 1,521
  • 5
  • 29
  • 51
  • 1
    try to set the `SearchResultsRow` as volatile. – Rod_Algonquin Mar 31 '15 at 04:03
  • can you elaborate please. – eqiz Mar 31 '15 at 04:04
  • 1
    If it is an arraylist then do this: `volatile ArrayList SearchResultsRow;` – Rod_Algonquin Mar 31 '15 at 04:06
  • Also, Search_Results_Item should be SearchResultsItem by convention – EDToaster Mar 31 '15 at 04:12
  • tried volatile it goes through everything, but still having same issue sometimes it comes out to 99 instead of 100 items. Keep in mind i'm always using the EXACT same data.. its Search_Results_Item just because the class itself is called that verbatim. I wouldn't guess that the _ would cause an issue? – eqiz Mar 31 '15 at 05:39
  • Post the SearchResultsRow class. And please, respect the Java naming conventions: thisIsAVariable, THIS_IS_A_CONSTANT, ThisIsAClassName. – JB Nizet Mar 31 '15 at 06:01

1 Answers1

1

In your case, both volatile and synchronizedList() won't work because the size checking logic and removing logic are separated. If you want to understand more about volatile, refer to When exactly do you use the volatile keyword in Java?.

To make your logic work properly, you need to make your method synchronized. Refer to this if you want to check the usage.

Community
  • 1
  • 1
Sanghyun Lee
  • 21,644
  • 19
  • 100
  • 126