2013-10-02 4 views
0

В этом нижеследующем коде; многие потоки BLOCKED в моей системе при добавлении новой конференции (addConference() API) в коллекцию из-за блокировки уровня системы (addConfLock). Добавление каждого нового потока конференции BLOCKED; и время добавления conf увеличивается из-за того, что каждый объект конференции должен быть создан/создан из БД путем выполнения сложного sql. Таким образом, время BLOCKING потока пропорционально транзакции DB.Обработка производительности по синхронизированному блоку

Я хотел бы выделить создание conf-объекта из блока SYNC добавления conf в коллекцию.
Я попробовал решение; Пожалуйста, направляйте меня в любое другое решение или объясните мне плохое мое решение.

Ниже приведен оригинальный код.

class Conferences extends OurCollectionImpl 
{ 
    //Contains all on going conferences 
} 

//single conference instance 
class Conf { 

    String confId; 
    Date startTime; 
    Date participants; 

    public void load() 
    { 
    // Load conference details from DB, and set its instance memebrs 
    } 
} 

class ConfMgr 
{ 

    Conferences confs = new Conferences(); 
    Object addConfLock = new Object(); 

    public boolean addConference(DBConn conn, String confID){ 

     synchronized(addConfLock) { 
     Conf conf = null; 

     conf = confs.get(confID) 
     if(conf != null) 
     { return true;} 

     conf = new Conf(); 
     conf.setConfID(confId); 
     conf.load(); //This is the BIG JOB with in SYNC BLOCK NEED TO SEPARATED 

     confs.add(conf); 
     } 
    } 

} 

// Мои решения

public boolean addConference(DBConn conn, String confID){ 

    Conf conf = null; 
    synchronized(addConfLock) { 
    conf = confs.get(confID) 
    if(conf != null) 
    { return true;} 
    conf = Conf.getInstance(confID, conn); 
    } 

    synchronized(conf.builded) { //SYNC is liberated to individual conf object level 
    if(conf.builded.equals("T")) { 
      return true; 
    } 
    conf.load(); 

    synchronized(addConfLock) { 
     confs.add(conf); 
    } 

    conf.builded = "T"; 
    } 

    } 
} 


//single conference instance 
class Conf { 

    String confId; 
    Date startTime; 
    Date participants; 
    String builded = "F"; //This is to avoid building object again. 
    private static HashMap<String, Conf> instanceMap = new HashMap<String, Conf>; 

    /* 
    * Below code will avoid two threads are requesting 
    * to create conference with same confID. 
    */ 
    public static Conf getInstance(DBConn conn, String confID){ 
     //This below synch will ensure singleTon created per confID 
     synchronized(Conf.Class) { 
      Conf conf = instanceMap.get(confID); 
      if(conf == null) { 
       conf = new Conf(); 
       instanceMap.put(confID, conf); 
      } 
      return conf; 
     }   
    } 

    public void load() 
    { 
    // Load conference details from DB, and set its instance memebrs 
    } 
} 
+2

Этот вопрос может быть лучше подходит для: http://codereview.stackexchange.com/ –

+0

Возможно ли получить данные из базы данных асинхронно? Вы можете добавить конфигурации в свою коллекцию, а затем отправить запросы загрузки асинхронно. Возможно, получение информации о конференциях в пакете по одному запросу БД может быть намного быстрее. –

+0

Как перенести этот вопрос на codereview.stackexchange? –

ответ

0

Проблема, как вы заявили, что вы все блокировки для каждого конф ид. Как насчет изменения конструкции механизма блокировки так, чтобы для каждого идентификатора conf была отдельная блокировка, тогда вы будете блокировать, только если транзакции для одного и того же conf id иначе выполнение будет параллельным.

Вот как йо может его получения идеальной:

  1. Ваш Conferences следует использовать ConcurrentHashMap для хранения различных конф.
  2. Возьмите замок на объект conf, который вы извлекаете из conf = confs.get(confID) i.e synchronize (conf).

Ваше приложение должно работать намного лучше.

EDIT:

Проблема в этом коде:

synchronized(addConfLock) { 
    conf = confs.get(confID) 
    if(conf != null) 
    { return true;} 
    conf = Conf.getInstance(confID, conn); 
    } 

Если вы используете ConcurrentHashMap в качестве коллекции вы можете удалить это, он обеспечивает API putIfAbsent, так что вам не нужно, чтобы зафиксировать ее.

+0

Спасибо! Lokesh. Но я не очень доволен. Давайте посмотрим другие ответы. –

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