从两个不同的线程同步锁定同一对象



基本上我有一个全局变量,例如...

Dim int1 as integer

然后我有两个异步函数,例如...

function bleh()
    int1 += 1
end function

function Meh()
     int1 -= 1
end function

这两个函数都由 Task.Run() 运行。

我想在这两个函数中使用 SyncLock。但是,MSDN 网站上给出的所有示例仅显示了在单个函数中使用 SyncLock 的示例。因此,我无法仅从 MSDN 描述中判断在全局变量上跨两个不同函数使用 SyncLock 是否"可以"。

我想做的是这样的:

Private Shared SyncObj as Object '<-- global
Dim int1 as integer '<-- global
Sub Form_Load(...)
     SyncObj = new Object
     Task.Run(Function() bleh())
     Task.Run(Function() Meh())
End Sub
Function bleh()
     SyncLock SyncObj
        int1 += 1
     End SyncLock
End Function
Function Meh()
     SyncLock SyncObj
        int1 -= 1
     End SyncLock
End Function

可以这样做吗?bleh() 会阻止 Meh() 更改 int1,反之亦然吗?谢谢!对不起,VB哈哈。

是的,没关系。 SyncLock就是为此而设计的。它避免其他线程在其他线程正在使用资源时访问该资源。我建议您执行 Console.Writeline 或 Debug.Writeline 来跟踪其输出。

添加 While true 以检查值的变化情况:

Sub Form_Load(...)
     SyncObj = new Object
     While true
      Task.Run(Function() bleh())
      Task.Run(Function() Meh())
     End while     
End Sub
Function bleh()
     SyncLock SyncObj
        int1 += 1
        Debug.Writeline("from thread bleh: " & int1.toString)
     End SyncLock
End Function
Function Meh()
     SyncLock SyncObj
        int1 -= 1
         Debug.Writeline("from thread meh: " & int1.toString)
     End SyncLock
End Function

同步时钟将阻止 bleh() 在 meh() 使用它时访问该代码,反之亦然。

编辑:我执行了您的代码,这是输出:

从线程 meh: -1

从线程 meh: -2

从螺纹漂白:-1

从螺纹漂白: 0

从螺纹漂白:1

从线程 meh: 0

从螺纹漂白:1

从线程 meh: 0

从螺纹漂白:1

从线程 meh: 0

从线程 meh: -1

从螺纹漂白: 0

从螺纹漂白:1

从线程 meh: 0

从螺纹漂白:1

从螺纹漂白:2

从线程 meh: 1

从线程 meh: 0

从线程 meh: -1

从螺纹漂白: 0

您阻止了对 int1 的访问,但如您所见,您无法控制一个线程在触发另一个线程之前执行两次。

使用另一个示例(例如,对于文件)可能很有用,它不能一次从两个线程访问,否则会给出异常。

这里有一个例子:

 Imports System.Threading.Tasks
Imports System.IO
Module Module2
    Dim SyncObj As Object
    Dim path As String = "c:testfile.text"
    Sub Main()
        SyncObj = New Object
        While True
            Task.Factory.StartNew(Function() bleh())
            Task.Factory.StartNew(Function() Meh())
        End While
    End Sub
    Function bleh()
        SyncLock SyncObj
            Using sw As New StreamWriter(path, True)
                sw.WriteLine("From bleh!!!")
            End Using
        End SyncLock
    End Function
    Function Meh()
        SyncLock SyncObj
            Using sw As New StreamWriter(path, True)
                sw.WriteLine("From meh!!!")
            End Using
        End SyncLock
    End Function
End Module

此示例在几秒钟内在路径文件上写入了 26814 行,没有任何异常,因此不会发生对资源的并发访问。

最新更新