有时Array不会从多个线程添加项目

时间:2015-03-31 03:54:23

标签: java multithreading

我觉得真的愚蠢甚至问这个问题,可能是愚蠢的问,因为我认为答案是"它应该永远不会那样",但我非常困在这我当前的问题,所以我想要问。

我有一个我创建的数组类......

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;

    }

我用我的方法称呼它......

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

我从使用..

同时启动的2个不同线程中添加项目
SearchResultsRow.add(new Search_Results_Item(sSite, sLocation, SortTitle, SortLinkURL, SortImageSRC, SortPrice, SortDescription, SortLocation,
                            SortDateTime, EPOCHDATETIME, sBaseURL));

然后我有一个持续运行的runnable并且这样做......

            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();

现在出于某种神奇的原因。有时会有一些项目被假设添加到SearchResults(并且前后计数确认已添加)实际上看不到并试图插入到SQLDatabase中(这就是SQLCOUNT ++是)。有时候只有1个记录,有时是所有记录的3.90%以上。

我不能为我的生活开始理解我所缺少的东西。

1 个答案:

答案 0 :(得分:1)

在您的情况下,volatilesynchronizedList()都不起作用,因为大小检查逻辑和删除逻辑是分开的。如果您想了解有关volatile的更多信息,请参阅When exactly do you use the volatile keyword in Java?

要使您的逻辑正常工作,您需要制作方法synchronized。如果要检查使用情况,请参阅this