2013-02-20 2 views
1

У меня есть DAOClass, который вызывается из многих Threads, как показано ниже для вставки в набор таблиц -Java поточно DAO

public class DAOClass 
{ 

private HashMap<String, HelperClass> insertBuffer; 


public DAOClass() 
{ 
    insertBuffer = new HashMap<String, HelperClass>();  
} 

public int[] createSomeTable(String key, SomeTableRecord someTableRecord) 
{ 
     List<SomeTableRecord> someTableRecList; 
     HelperClass buf = insertBuffer.get(key); 
     if (buf == null) 
     { 
      buf = new HelperClass(); 
      insertBuffer.put(key, buf); 
     } 

     someTableRecList = buf.getSomeTableBuffer(); 
     someTableRecList.add(someTableRecord); 

     if(someTableRecList.size() >= Global.limit()) 
     { 
      return flushSomeTableInsertCache(key); 
     } 
     else 
     { 
      return null; 
     } 
} 

public int[] flushSomeTableInsertCache(String key) 
{ 
    HelperClass buf = insertBuffer.get(key); 
    int[] retVal = null; 
    if (buf != null && buf.getSomeTableBuffer() != null) 
    { 
     retVal = createSomeTableBuffered(buf.getSomeTableBuffer()); 
     buf.getSomeTableBuffer().clear(); 
    } 
    return retVal; 
} 

} 

public int[] createSomeTableBuffered(final List<SomeTableRecord> someTableRecordList) 
{ 
    INSERT QUERY GOES HERE from LIST.. 
} 
} 

Различные темы называют createSomeTable метод, который добавляет к ArrayList из в вспомогательном классе. Существует HashMap, но ключ перекрывается то есть то же ключ поражен несколько потоков одновременно, тем самым развращает Hashmap и несвоевременные промывки ..

Вспомогательного класс следующим образом -

class HelperClass { 

private String key; 
private ArrayList<SomeTableRecord> someTableBuffer; 
private ArrayList<SomeTable1Record> someTable1Buffer; 


HelperClass() { 

    someTableBuffer = new ArrayList<SomeTableRecord>(); 
    someTable1Buffer = new ArrayList<SomeTable1Record>(); 

} 

public ArrayList<SomeTableRecord> getSomeTableBuffer() { 
    return someTableBuffer; 
} 

public ArrayList<SomeTable1Record> getSomeTable1Buffer() { 
    return someTable1Buffer; 
} 
} 

Но это, видимо, не поточно поскольку ключ не является непересекающимся. Можете ли вы предложить некоторую коррекцию в классах, чтобы она была потоковой.

+0

Кто называет 'flushSomeTableInsertCache()' тот же поток, который вставил элементы, или другой 'Thread'? – gaborsch

+0

@GaborSch: Я думаю, что поток, который превысил ограничение кэша: 'if (someTableRecList.size()> = Global.limit())' ... – home

+0

Thnaks, я пропустил эту строку ... обновил ответ соответственно – gaborsch

ответ

0

Вы должны использовать ArrayList<HelperClass>, чем HashMap. Во избежание конфликтов используйте

public synchronized int[] createSomeTable(String key, SomeTableRecord someTableRecord) 

для защиты вашего буфера.

UPDATE:

Для защиты буфера даже весной, добавить synchronized к flushSomeTableInsertCache, а также:

public synchronized int[] flushSomeTableInsertCache(String key) 

На самом деле вы не используете key S только для идентификации элементов.

В противном случае это не является хорошей стратегией для отслеживания ключевых столкновений таким образом, потому что они могут даже произойти между двумя флешами, поэтому вы должны либо проверить их в базе данных, либо иметь отдельный HashSet для ключей (если вы уверены что у вас есть все ключи).

0

Вместо этого используйте класс ConcurrentHashMap.

0

insertBuffer - это единственное государство здесь. Изменение его содержимого в многопоточной среде может привести к неожиданному поведению. Вы можете либо синхронизировать доступ к нему, либо использовать ConcurrentHashMap вместо HashMap.

0

Я бы использовал synchronized методы, а не ConcurrentHashMap. Однако использование ConcurrentHashMap может также решить вашу проблему с потоковой безопасностью.

0

Самый простой способ разделить использование - создать один объект DAOClass для каждого потока.

+0

He имеет общий буфер ... – gaborsch

+0

flushSomeTableInsertCache вызывается из DAOClass, который является Singleton in Spring XML. Но я должен сказать, что я пропустил одну деталь. что этот метод - «flushSomeTableInsertCache», также вызывается из отдельных потоков, а также для очистки в конце прогона потока в случае, если он не был сброшен из самого DAO. Это тоже проблема .. – fortm

0

Измените свою реализацию на ConcurrentHashMap, которая решит проблему параллелизма.

Смежные вопросы