使用多线程[VB.NET]拾取两次值

使用多线程[VB.NET]拾取两次值,vb.net,multiprocessing,Vb.net,Multiprocessing,我正在尝试将一些多线程应用到我的代码中,因此我尝试使用一些简单的任务进行练习。 在下面的简单代码中,我希望每个线程获取计数器(m)的一个值,然后增加其值,然后使用先前获取的值进行排序,并将其结果复制到列表(listL)中。。 不幸的是,我无法阻止线程两次获取相同的值。。。 这可能很琐碎,但我找不到合适的解决方案。。。 提前谢谢 马里奥 导入系统线程 模块1 公共m作为UShort=0 Dim listL作为新列表(整数) 副标题() Dim t1作为新线程(TestMultiThreading的

我正在尝试将一些多线程应用到我的代码中,因此我尝试使用一些简单的任务进行练习。 在下面的简单代码中,我希望每个线程获取计数器(m)的一个值,然后增加其值,然后使用先前获取的值进行排序,并将其结果复制到列表(listL)中。。 不幸的是,我无法阻止线程两次获取相同的值。。。 这可能很琐碎,但我找不到合适的解决方案。。。 提前谢谢

马里奥

导入系统线程
模块1
公共m作为UShort=0
Dim listL作为新列表(整数)
副标题()
Dim t1作为新线程(TestMultiThreading的地址)
Dim t2作为新线程(TestMultiThreading的地址)
t1.启动(“a”)
t2.启动(“b”)
t1.Join()
t2.Join()
对于m,作为整数=0到listL.Count-1
对于n作为整数=m+1到listL.Count-1
如果listL(n)=listL(m),则Debug.Print(“相同的{0}{1}”,n,m)
下一个
下一个m
listL.Clear()
端接头
公共子测试多线程(ByVal X作为字符)
将lobj1设置为新对象
作为整数的Dim p
当m<100时执行此操作
同步锁lobj1
p=m
m+=1
端同步
“各种计算。。。
"最终,
列表添加(m)
环
lobj1=无
Debug.WriteLine(“结束”&X)
端接头
端模块

我创建了这个测试。看看它们的区别,特别是锁对象是如何在循环之外的,并且值p被添加到列表中,而不是m

Module Module1
Public m As Integer = 0
Dim listL As New List(Of String)

Sub Main()
    Dim t1 As New Threading.Thread(AddressOf TestMultiThreading)
    Dim t2 As New Threading.Thread(AddressOf TestMultiThreading)

    t1.Start("a")
    t2.Start("b")
    Threading.Thread.Sleep(0)
    t1.Join()
    t2.Join()

    For xm As Integer = 0 To listL.Count - 1
        Debug.WriteLine(listL(xm))
        For n As Integer = xm + 1 To listL.Count - 1
            If listL(n) = listL(xm) Then
                Debug.Print("same {0} {1}", n, xm)
            End If
        Next n
    Next xm

    listL.Clear()
    Stop
End Sub

Dim lobj1 As New Object

Public Sub TestMultiThreading(ByVal X As Object)

    Dim p As Integer
    Dim c As String = DirectCast(X, String)
    Do While m < 100
        SyncLock lobj1
            p = m
            m += 1
        End SyncLock
        Threading.Thread.Sleep(0) ' various calculations ...
        ' eventually
        'listL.Add(p.ToString & c) 'for debug
        listL.Add(p.ToString)
    Loop


    Debug.WriteLine("end " & c)

End Sub

End Module
模块1
公共m作为整数=0
Dim listL作为新列表(字符串)
副标题()
Dim t1作为新的Threading.Thread(TestMultiThreading的地址)
Dim t2作为新的Threading.Thread(TestMultiThreading的地址)
t1.启动(“a”)
t2.启动(“b”)
线程。线程。睡眠(0)
t1.Join()
t2.Join()
对于xm As Integer=0到listL.Count-1
Debug.WriteLine(listL(xm))
对于n,整数=xm+1到listL.Count-1
如果listL(n)=listL(xm),则
Print(“相同的{0}{1}”,n,xm)
如果结束
下一个
下一个xm
listL.Clear()
停止
端接头
将lobj1设置为新对象
公共子测试多线程(ByVal X作为对象)
作为整数的Dim p
尺寸c为字符串=DirectCast(X,字符串)
当m<100时执行此操作
同步锁lobj1
p=m
m+=1
端同步
线程。线程。睡眠(0)的各种计算。。。
"最终,
“listL.Add(p.ToString&c)”用于调试
列表添加(p.ToString)
环
Debug.WriteLine(“结束”&c)
端接头
端模块

我明白了,非常感谢您抽出时间,我得说我错过了在sub之外声明的lock Obj的含义……或者……是为了让它成为“全球的”吗?在这种情况下,在我糟糕的代码中,锁没有锁定任何东西,我猜:P,但我没有掌握*.thread.sleep(0)使用…sleep是为了确保两个线程都在运行,因为我没有实际的代码。锁是本地的,所以每个线程都有自己的锁,将它移到外部意味着每个线程都使用相同的锁。
Module Module1
Public m As Integer = 0
Dim listL As New List(Of String)

Sub Main()
    Dim t1 As New Threading.Thread(AddressOf TestMultiThreading)
    Dim t2 As New Threading.Thread(AddressOf TestMultiThreading)

    t1.Start("a")
    t2.Start("b")
    Threading.Thread.Sleep(0)
    t1.Join()
    t2.Join()

    For xm As Integer = 0 To listL.Count - 1
        Debug.WriteLine(listL(xm))
        For n As Integer = xm + 1 To listL.Count - 1
            If listL(n) = listL(xm) Then
                Debug.Print("same {0} {1}", n, xm)
            End If
        Next n
    Next xm

    listL.Clear()
    Stop
End Sub

Dim lobj1 As New Object

Public Sub TestMultiThreading(ByVal X As Object)

    Dim p As Integer
    Dim c As String = DirectCast(X, String)
    Do While m < 100
        SyncLock lobj1
            p = m
            m += 1
        End SyncLock
        Threading.Thread.Sleep(0) ' various calculations ...
        ' eventually
        'listL.Add(p.ToString & c) 'for debug
        listL.Add(p.ToString)
    Loop


    Debug.WriteLine("end " & c)

End Sub

End Module