同步块上的性能处理

  • 本文关键字:性能 处理 同步 java
  • 更新时间 :
  • 英文 :


在下面的代码中;由于系统级锁定(addConfLock),在将新的会议(addConference()API)添加到集合中时,许多线程在我的系统中被阻止。每个新会议线程的添加都被阻止;并且增加了添加 conf 的时间,因为每个会议对象都必须通过执行复杂的 sql 从数据库创建/构建。因此,线程阻塞时间与数据库事务成正比。

我想将 conf 对象创建与将 conf 添加到集合中的 SYNC 块分开。
我尝试了一个解决方案;如果有任何其他解决方案,请指导我或解释我的解决方案的缺点。

下面是原始代码。

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
    }
}

正如您所说,问题是您为每个 conf id 锁定了所有内容。如何更改锁定机制的设计,以便每个 conf id 都有单独的锁,然后只有当事务针对相同的 conf id 时,您才会锁定,否则执行将是并行的。

以下是 yo 如何实现它:

  1. 您的Conferences应该使用COncurrentHashMap来存储不同的conf。
  2. 锁定您从conf = confs.get(confID)检索的conf对象,即同步(conf)。

然后,您的应用程序应该性能会更好。

编辑:

问题出在此代码中:

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

如果您使用ConcurrentHashMap作为集合,则可以将其删除,它提供了一个 api putIfAbsent,因此您无需锁定它。

最新更新