You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@rocketmq.apache.org by GitBox <gi...@apache.org> on 2019/03/21 01:39:28 UTC

[GitHub] [rocketmq] yuyijq opened a new issue #1101: 改进GroupCommitService里锁的可理解性

yuyijq opened a new issue #1101: 改进GroupCommitService里锁的可理解性
URL: https://github.com/apache/rocketmq/issues/1101
 
 
   GroupCommitService(at CommitLog)里使用了好几个锁,并且有两个地方在可变变量上加锁,花了较长时间才弄明白这几个锁的真实目的,是不是可以将锁改成下面的形式,除了提高可理解性外,也不会出现sonar warning,这样改了之后性能也没有什么降低:
   ```java
       class GroupCommitService extends FlushCommitLogService {
           private volatile List<GroupCommitRequest> requestsWrite = new ArrayList<GroupCommitRequest>();
           private volatile List<GroupCommitRequest> requestsRead = new ArrayList<GroupCommitRequest>();
   
           public synchronized void putRequest(final GroupCommitRequest request) {
              //去掉对requestsWrite的加锁
               this.requestsWrite.add(request);
               if (hasNotified.compareAndSet(false, true)) {
                   waitPoint.countDown(); // notify
               }
           }
   
          //在这里增加方法同步块
           private synchronized void swapRequests() {
               List<GroupCommitRequest> tmp = this.requestsWrite;
               this.requestsWrite = this.requestsRead;
               this.requestsRead = tmp;
           }
   
           private void doCommit() {
                   //去掉对requestsRead加锁
                   if (!this.requestsRead.isEmpty()) {
                       for (GroupCommitRequest req : this.requestsRead) {
                           // There may be a message in the next file, so a maximum of
                           // two times the flush
                           boolean flushOK = false;
                           for (int i = 0; i < 2 && !flushOK; i++) {
                               flushOK = CommitLog.this.mappedFileQueue.getFlushedWhere() >= req.getNextOffset();
   
                               if (!flushOK) {
                                   CommitLog.this.mappedFileQueue.flush(0);
                               }
                           }
   
                           req.wakeupCustomer(flushOK);
                       }
   
                       long storeTimestamp = CommitLog.this.mappedFileQueue.getStoreTimestamp();
                       if (storeTimestamp > 0) {
                           CommitLog.this.defaultMessageStore.getStoreCheckpoint().setPhysicMsgTimestamp(storeTimestamp);
                       }
   
                       this.requestsRead.clear();
                   } else {
                       // Because of individual messages is set to not sync flush, it
                       // will come to this process
                       CommitLog.this.mappedFileQueue.flush(0);
                   }
           }
   
           public void run() {
               CommitLog.log.info(this.getServiceName() + " service started");
   
               while (!this.isStopped()) {
                   try {
                       this.waitForRunning(10);
                       this.doCommit();
                   } catch (Exception e) {
                       CommitLog.log.warn(this.getServiceName() + " service has exception. ", e);
                   }
               }
   
               // Under normal circumstances shutdown, wait for the arrival of the
               // request, and then flush
               try {
                   Thread.sleep(10);
               } catch (InterruptedException e) {
                   CommitLog.log.warn("GroupCommitService Exception, ", e);
               }
              this.swapRequests();
              this.doCommit();
               CommitLog.log.info(this.getServiceName() + " service end");
           }
   
           @Override
           protected void onWaitEnd() {
               this.swapRequests();
           }
       }
   ```

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services