ReentrantLock:多个线程可以同时获取写锁定吗?

时间:2016-07-08 15:34:55

标签: java multithreading concurrency

我有一个方法fetchAndMoveMessageInfo,它将被多个线程并发访问,它执行以下操作:

  1. 如果全局队列缓存为空:通过执行读取操作填充队列缓存(ConcurrentLinkedQueue)但确保只有一个线程执行此项目,其他应该等待
  2. 如果缓存不为空,则只需安全弹出一个Item线程。我的意思是没有两个线程弹出相同的项目。
  3. 对于第二个要求,我使用了ConcurrentLinkedQueue来确保没有线程弹出相同的项目。

    对于第一个要求,我使用了ReentrantLock Lock,以便获取写锁定的线程应该执行db read ops以填充其他读取器应该等待缓存填充。填充缓存后,读取同时对队列进行线程化。

    我有以下查询:

    1. 我的上述设计可以吗?但我观察到,当dbinfo中的messageinfo计数减少时,随着messageinfos数量下降,吞吐量急剧下降。我认为这是因为当messsgeInofs较少时,争用和更多数量的db读取。例如,如果writer获取600 messageInfos,那么所有其他线程将从缓存中获得599的剩余部分。但是如果编写器(获取写锁定并从数据库读取的那个)只提取了2条消息,则消息数量会减少。这将导致争用和更多数量的数据库查询。我的疑问是正确的吗?我是否必须忍受这种情况,还是有更好的方法来处理这个问题?

    2. 我还观察到一个同步的方法的争用,并且只能调用getDequeueMessageInfo。我不知道当ReentrantLock锁定在一次只有作者时,这个方法如何得到争用。

    3. 有没有更好的设计?请提出建议。

    4. 以下是我的代码和JFR争用快照的快照。

      Sub GetSheets()
      Dim sFileName As String
      Dim Path As String
      Dim wbNew As Workbook
      Dim tmpWb As Workbook
      Dim tSheets As Long
      Dim iSheets As Long
          iSheets = 0
          Set wbNew = gWrkBook() 'creat new workbook
      
          Path = gGetFolder("Any default folder path")
          If gSearch(Path, "\", "LastChar") > 0 Then
              Path = Path + "\"
          End If
          Filename = dir(Path & "*.xlsx")
      
          Do While Filename <> ""
              Workbooks.Open Filename:=Path & Filename, ReadOnly:=True
              Set tmpWb = ActiveWorkbook
              tSheets = tmpWb.Worksheets.Count
      
              If tSheets > 0 Then
                  iSheets = 1
                  tmpWb.Sheets(iSheets).Activate
      
                  For iSheets = 1 To tSheets
                      tmpWb.Sheets(iSheets).Activate
                      Range("A2").Select
      
                      If Range("A2").Value <> "" Then
                          sFileName = tmpWb.Name + "-" + CStr(iSheets)
                          sFileName = Replace(sFileName, ".xlsx", "")
                          tmpWb.Sheets(iSheets).Name = sFileName
                          wbNew.Activate
                          tmpWb.Sheets(iSheets).Copy After:=wbNew.Sheets(1)
      
                      Else
                      End If
                      tmpWb.Activate
                  Next
              End If
      
              Workbooks(Filename).Close savechanges:=False
              Filename = dir()
      
          Loop
      End Sub
      
          Public Function gGetFolder(strPath As String) As String
      
      Dim fldr As FileDialog
      
          Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
      
          With fldr
              .Title = "Select a Folder"
              .AllowMultiSelect = False
              .InitialFileName = strPath
      
              If .Show <> -1 Then GoTo NextCode
                  sItem = .SelectedItems(1)
          End With
      
      NextCode:
          gGetFolder = sItem
          Set fldr = Nothing
      
      End Function
      

0 个答案:

没有答案