c# 多线程--Lock
最近在学习多线程编程,以下代码出自《C#2.0完全参考手册》,稍有改动
当使用多个线程是,有时需要协调两个或多个线程的行为,完成这个步骤的过程成为同步(Synchornization)。使用同步机制最常见的原因是,两个或多个线程需要访问同一个共享资源,而该资源每次只能供一个线程使用……
同步的关键是引入锁(Lock)的概念,。锁用于控制对对象中的代码块的访问,当一个线程锁定一个对象时,其他线程就不能访问已锁定的代码块。只有当线程释放该锁时,其他线程才能锁定该对象。
下面的代码由两个线程执行一模一样的代码(共享资源),输出同样的结果

Code
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 using System.Threading;
7
8 namespace thread
9 {
10 class Sumarry
11 {
12 int sum;
13
14 public int sumIt(int[] nums)
15 {
16 //lock the entire method
17 lock (this)
18 {
19 //reset sum;
20 //保证让每个进程只计算自己的
21 sum = 0;
22 for (int i = 0; i < nums.Length; i++)
23 {
24 sum += nums[i];
25 //Thread.CurrentThread.Name 当前运行的进程名称
26 Console.WriteLine("Runing total for " + Thread.CurrentThread.Name + " is " + sum);
27 Thread.Sleep(500);
28 }
29 return sum;
30 }
31 }
32 }
33
34 class TestThread
35 {
36 public Thread thrd;
37 int [] a;
38 int answer;
39
40 //static 静态的可以共享,
41 static Sumarry sa = new Sumarry();
42 //如果使用非静态的,则没有共享,lock与不lock就没有区别了,而且也体现不出同步
43 //同步需要"共享资源"
44 // private Sumarry sa = new Sumarry();
45
46 public TestThread(string name, int[] nums)
47 {
48 a = nums;
49 thrd = new Thread(new ThreadStart (this.run));
50 thrd.Name = name;
51 thrd.Start();
52 }
53
54 void run()
55 {
56 Console.WriteLine(thrd.Name + "starting.");
57 answer = sa.sumIt(a);
58 Console.WriteLine("sum for " + thrd.Name + " is " + answer);
59
60 Console.WriteLine(thrd.Name + "terminating");
61 }
62 }
63 class syn
64 {
65 public static void Main()
66 {
67 int[] a = { 1, 2, 3, 4, 5 };
68
69 TestThread mt1 = new TestThread("child #1", a);
70
71 TestThread mt2 = new TestThread("child #2", a);
72
73 mt1.thrd.Join();
74 mt2.thrd.Join();
75 }
76 }
77
78
79 }
80上述是在方法内部Lock,但是如果想同步访问并非自己创建的类定义的方法,但他本身并不是同步的,对于这种由第三方编写而我们无权访问它的源代码的类,就
不能像上面那样处理了。 解决办法是lock语句中指定要锁定的对象。这羊对象之外就不能任意的访问它,程序代码如下,注意Lock的位置

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace thread
{
class Sumarry2
{
int sum;
public int sumIt(int[] nums)
{
sum = 0;
for (int i = 0; i < nums.Length; i++)
{
sum += nums[i];
//Thread.CurrentThread.Name 当前运行的进程名称
Console.WriteLine("Runing total for " + Thread.CurrentThread.Name + " is " + sum);
Thread.Sleep(500);
}
return sum;
}
}
class TestThread2
{
public Thread thrd;
int[] a;
int answer;
//static 静态的可以共享,
static Sumarry2 sa2 = new Sumarry2();
//如果使用非静态的,则没有共享,lock与不lock就没有区别了,而且也体现不出同步
//同步需要"共享资源"
// private Sumarry2 sa2 = new Sumarry2();
public TestThread2(string name, int[] nums)
{
a = nums;
thrd = new Thread(new ThreadStart(this.run));
thrd.Name = name;
thrd.Start();
}
void run()
{
Console.WriteLine(thrd.Name + "starting.");
//同步访问并非自己创建的类定义的方法sa2.sumIt(a),类sa2本身不是同步的
//第三方无全访问类的源代码,
//不能为类Sumarry2添加lock,就lock要锁定的对象。使对象之外的代码不能任意访问它
lock (sa2)
answer = sa2.sumIt(a);
Console.WriteLine("sum for " + thrd.Name + " is " + answer);
Console.WriteLine(thrd.Name + "terminating");
}
}
class syn2
{
public static void Main()
{
int[] a = { 1, 2, 3, 4, 5 };
TestThread2 mt1 = new TestThread2("child #1", a);
TestThread2 mt2 = new TestThread2("child #2", a);
mt1.thrd.Join();
mt2.thrd.Join();
}
}
}
当使用多个线程是,有时需要协调两个或多个线程的行为,完成这个步骤的过程成为同步(Synchornization)。使用同步机制最常见的原因是,两个或多个线程需要访问同一个共享资源,而该资源每次只能供一个线程使用……
同步的关键是引入锁(Lock)的概念,。锁用于控制对对象中的代码块的访问,当一个线程锁定一个对象时,其他线程就不能访问已锁定的代码块。只有当线程释放该锁时,其他线程才能锁定该对象。
下面的代码由两个线程执行一模一样的代码(共享资源),输出同样的结果
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 using System.Threading;
7
8 namespace thread
9 {
10 class Sumarry
11 {
12 int sum;
13
14 public int sumIt(int[] nums)
15 {
16 //lock the entire method
17 lock (this)
18 {
19 //reset sum;
20 //保证让每个进程只计算自己的
21 sum = 0;
22 for (int i = 0; i < nums.Length; i++)
23 {
24 sum += nums[i];
25 //Thread.CurrentThread.Name 当前运行的进程名称
26 Console.WriteLine("Runing total for " + Thread.CurrentThread.Name + " is " + sum);
27 Thread.Sleep(500);
28 }
29 return sum;
30 }
31 }
32 }
33
34 class TestThread
35 {
36 public Thread thrd;
37 int [] a;
38 int answer;
39
40 //static 静态的可以共享,
41 static Sumarry sa = new Sumarry();
42 //如果使用非静态的,则没有共享,lock与不lock就没有区别了,而且也体现不出同步
43 //同步需要"共享资源"
44 // private Sumarry sa = new Sumarry();
45
46 public TestThread(string name, int[] nums)
47 {
48 a = nums;
49 thrd = new Thread(new ThreadStart (this.run));
50 thrd.Name = name;
51 thrd.Start();
52 }
53
54 void run()
55 {
56 Console.WriteLine(thrd.Name + "starting.");
57 answer = sa.sumIt(a);
58 Console.WriteLine("sum for " + thrd.Name + " is " + answer);
59
60 Console.WriteLine(thrd.Name + "terminating");
61 }
62 }
63 class syn
64 {
65 public static void Main()
66 {
67 int[] a = { 1, 2, 3, 4, 5 };
68
69 TestThread mt1 = new TestThread("child #1", a);
70
71 TestThread mt2 = new TestThread("child #2", a);
72
73 mt1.thrd.Join();
74 mt2.thrd.Join();
75 }
76 }
77
78
79 }
80
不能像上面那样处理了。 解决办法是lock语句中指定要锁定的对象。这羊对象之外就不能任意的访问它,程序代码如下,注意Lock的位置
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace thread
{
class Sumarry2
{
int sum;
public int sumIt(int[] nums)
{
sum = 0;
for (int i = 0; i < nums.Length; i++)
{
sum += nums[i];
//Thread.CurrentThread.Name 当前运行的进程名称
Console.WriteLine("Runing total for " + Thread.CurrentThread.Name + " is " + sum);
Thread.Sleep(500);
}
return sum;
}
}
class TestThread2
{
public Thread thrd;
int[] a;
int answer;
//static 静态的可以共享,
static Sumarry2 sa2 = new Sumarry2();
//如果使用非静态的,则没有共享,lock与不lock就没有区别了,而且也体现不出同步
//同步需要"共享资源"
// private Sumarry2 sa2 = new Sumarry2();
public TestThread2(string name, int[] nums)
{
a = nums;
thrd = new Thread(new ThreadStart(this.run));
thrd.Name = name;
thrd.Start();
}
void run()
{
Console.WriteLine(thrd.Name + "starting.");
//同步访问并非自己创建的类定义的方法sa2.sumIt(a),类sa2本身不是同步的
//第三方无全访问类的源代码,
//不能为类Sumarry2添加lock,就lock要锁定的对象。使对象之外的代码不能任意访问它
lock (sa2)
answer = sa2.sumIt(a);
Console.WriteLine("sum for " + thrd.Name + " is " + answer);
Console.WriteLine(thrd.Name + "terminating");
}
}
class syn2
{
public static void Main()
{
int[] a = { 1, 2, 3, 4, 5 };
TestThread2 mt1 = new TestThread2("child #1", a);
TestThread2 mt2 = new TestThread2("child #2", a);
mt1.thrd.Join();
mt2.thrd.Join();
}
}
}
注意上述代码的54行,lock对象,看对比效果的话就把上述代码的54行屏蔽,就可以了。

浙公网安备 33010602011771号