//一个简单的示例
//HelloWordThread.cs//------------------------using System;
using System.Threading;

public class Test

...{
static void Main()

...{
ThreadStart job = new ThreadStart(ThreadJob);
Thread thread = new Thread(job);
thread.Start();
for (int i=0; i < 5; i++)

...{
Console.WriteLine ("Main thread: {0}", i);
Thread.Sleep(1000);
}
}
static void ThreadJob()

...{
for (int i=0; i < 10; i++)

...{
Console.WriteLine ("Other thread: {0}", i);
Thread.Sleep(500);
}
}
}结果:
Main thread: 0
Other thread: 0
Other thread: 1
Main thread: 1
Other thread: 2
Other thread: 3
Main thread: 2
Other thread: 4
Other thread: 5
Main thread: 3
Other thread: 6
Other thread: 7
Main thread: 4
Other thread: 8
Other thread: 9
//UsingDelegate.cs
------------------------------------
using System;
using System.Threading;

public class Test

...{
static void Main()

...{
Counter foo = new Counter();
ThreadStart job = new ThreadStart(foo.Count);
Thread thread = new Thread(job);
thread.Start();
for (int i=0; i < 5; i++)

...{
Console.WriteLine ("Main thread: {0}", i);
Thread.Sleep(1000);
}
}
}

public class Counter

...{
public void Count()

...{

for (int i=0; i < 10; i++) ...{ Console.WriteLine ("Other thread: {0}", i);
Thread.Sleep(500);
}
}
}


using System.Threading;
public class Test
...{
static void Main()
...{
ThreadStart job = new ThreadStart(ThreadJob);
Thread thread = new Thread(job);
thread.Start();
for (int i=0; i < 5; i++)
...{
Console.WriteLine ("Main thread: {0}", i);
Thread.Sleep(1000);
}
}
static void ThreadJob()
...{
for (int i=0; i < 10; i++)
...{
Console.WriteLine ("Other thread: {0}", i);
Thread.Sleep(500);
}
}
}结果:
Main thread: 0
Other thread: 0
Other thread: 1
Main thread: 1
Other thread: 2
Other thread: 3
Main thread: 2
Other thread: 4
Other thread: 5
Main thread: 3
Other thread: 6
Other thread: 7
Main thread: 4
Other thread: 8
Other thread: 9
//UsingDelegate.cs
------------------------------------
using System;
using System.Threading;
public class Test
...{
static void Main()
...{
Counter foo = new Counter();
ThreadStart job = new ThreadStart(foo.Count);
Thread thread = new Thread(job);
thread.Start();
for (int i=0; i < 5; i++)
...{
Console.WriteLine ("Main thread: {0}", i);
Thread.Sleep(1000);
}
}
}
public class Counter
...{
public void Count()
...{
for (int i=0; i < 10; i++) ...{ Console.WriteLine ("Other thread: {0}", i);
Thread.Sleep(500);
}
}
}

二、线程中的参数传递
使用类、类的方法或类的属性都可以向线程传递参数:{ string url; public UrlDownloader (string url) { this.url = url; } public void Download() {
public class UrlDownloader
WebClient wc = new WebClient();
Console.WriteLine("Downloading " + url); byte[] buffer = wc.DownloadData (url); string download = Encoding.ASCII.GetString(buffer); Console.WriteLine(download); Console.WriteLine("Download successful.");
//这里你可以将download进行保存等处理...... } } [... 在另一个类中使用它们...] UrlDownloader downloader = new UrlDownloader (yourUrl); new Thread (new ThreadStart (downloader.Download)).Start();
注意参数是如何传递的。
在.NET 2.0中还可以这样:
(CODE-BESIDE)
方式一:
ThreadStart starter = delegate { Download(yourUrl); });
new Thread(starter).Start();
//使用线程池
WaitCallback callback = delegate (object state) { Download ((string)state); };
ThreadPool.QueueUserWorkItem (callback, yourUrl);
方式二(使用ParameterizedThreadStart):
Thread t = new Thread (new ParameterizedThreadStart(DownloadUrl));
t.Start (myUrl);
static void DownloadUrl(object url)
{
// ....
}
三、线程内部是如何进行的?
看一下以下两个例子的运行结果://TestThread.csusing System;
using System.Threading;
public class Test
...{
static int count=0;
![]()
static void Main()
...{
ThreadStart job = new ThreadStart(ThreadJob);
Thread thread = new Thread(job);
thread.Start();
![]()
for (int i=0; i < 5; i++)
...{
count++;
}
![]()
thread.Join();
Console.WriteLine ("Final count: {0}", count);
}
![]()
static void ThreadJob()
...{
for (int i=0; i < 5; i++)
...{
count++;
}
}
}
//InnerDataThread.csusing System;
using System.Threading;
public class Test
...{
static int count=0;
![]()
static void Main()
...{
ThreadStart job = new ThreadStart(ThreadJob);
Thread thread = new Thread(job);
thread.Start();
![]()
for (int i=0; i < 5; i++)
...{
int tmp = count;
Console.WriteLine ("Read count={0}", tmp);
Thread.Sleep(50);
tmp++;
Console.WriteLine ("Incremented tmp to {0}", tmp);
Thread.Sleep(20);
count = tmp;
Console.WriteLine ("Written count={0}", tmp);
Thread.Sleep(30);
}
![]()
thread.Join();
Console.WriteLine ("Final count: {0}", count);
}
![]()
static void ThreadJob()
...{
for (int i=0; i < 5; i++)
...{
int tmp = count;
Console.WriteLine (" Read count={0}", tmp);
Thread.Sleep(20);
tmp++;
Console.WriteLine (" Incremented tmp to {0}", tmp);
Thread.Sleep(10);
count = tmp;
Console.WriteLine (" Written count={0}", tmp);
Thread.Sleep(40);
}
}
}
Read count=0
Read count=0
Incremented tmp to 1
Written count=1
Incremented tmp to 1
Written count=1
Read count=1
Incremented tmp to 2
Read count=1
Written count=2
Read count=2
Incremented tmp to 2
Incremented tmp to 3
Written count=2
Written count=3
Read count=3
Read count=3
Incremented tmp to 4
Incremented tmp to 4
Written count=4
Written count=4
Read count=4
Read count=4
Incremented tmp to 5
Written count=5
Incremented tmp to 5
Written count=5
Read count=5
Incremented tmp to 6
Written count=6
Final count: 6
|
再比较下面这个例子:
//使用Monitor.Enter/Exit
//MonitorThread.cs
using System;
using System.Threading;
public class Test
...{
static int count=0;
static readonly object countLock = new object();
static void Main()
...{
ThreadStart job = new ThreadStart(ThreadJob);
Thread thread = new Thread(job);
thread.Start();
for (int i=0; i < 5; i++)
...{
Monitor.Enter(countLock);
int tmp = count;
Console.WriteLine ("Read count={0}", tmp);
Thread.Sleep(50);
tmp++;
Console.WriteLine ("Incremented tmp to {0}", tmp);
Thread.Sleep(20);
count = tmp;
Console.WriteLine ("Written count={0}", tmp);
Monitor.Exit(countLock);
Thread.Sleep(30);
}
thread.Join();
Console.WriteLine ("Final count: {0}", count);
}
static void ThreadJob()
...{
for (int i=0; i < 5; i++)
...{
Monitor.Enter(countLock);
int tmp = count;
Console.WriteLine (" Read count={0}", tmp);
Thread.Sleep(20);
tmp++;
Console.WriteLine (" Incremented tmp to {0}", tmp);
Thread.Sleep(10);
count = tmp;
Console.WriteLine (" Written count={0}", tmp);
Monitor.Exit(countLock);
Thread.Sleep(40);
}
}
}
结果与上例InnerDataThread.cs是不一样的,原因就在于Monitor的使用了。
Read count=0
Incremented tmp to 1
Written count=1
Read count=1
Incremented tmp to 2
Written count=2
Read count=2
Incremented tmp to 3
Written count=3
Read count=3
Incremented tmp to 4
Written count=4
Read count=4
Incremented tmp to 5
Written count=5
Read count=5
Incremented tmp to 6
Written count=6
Read count=6
Incremented tmp to 7
Written count=7
Read count=7
Incremented tmp to 8
Written count=8
Read count=8
Incremented tmp to 9
Written count=9
Read count=9
Incremented tmp to 10
Written count=10
Final count: 10
|
下面使用lock来锁定线程:
// LockThread.cs
using System;
using System.Threading;
public class Test
...{
static int count=0;
static readonly object countLock = new object();
static void Main()
...{
ThreadStart job = new ThreadStart(ThreadJob);
Thread thread = new Thread(job);
thread.Start();
for (int i=0; i < 5; i++)
...{
lock (countLock)
...{
int tmp = count;
Console.WriteLine ("Read count={0}", tmp);
Thread.Sleep(50);
tmp++;
Console.WriteLine ("Incremented tmp to {0}", tmp);
Thread.Sleep(20);
count = tmp;
Console.WriteLine ("Written count={0}", tmp);
}
Thread.Sleep(30);
}
thread.Join();
Console.WriteLine ("Final count: {0}", count);
}
static void ThreadJob()
...{
for (int i=0; i < 5; i++)
...{
lock (countLock)
...{
int tmp = count;
Console.WriteLine (" Read count={0}", tmp);
Thread.Sleep(20);
tmp++;
Console.WriteLine (" Incremented tmp to {0}", tmp);
if (count < 100)
throw new Exception();
Thread.Sleep(10);
count = tmp;
Console.WriteLine (" Written count={0}", tmp);
}
Thread.Sleep(40);
}
}
}
结果如何?与MonitorThread.cs比较一下,再想想看。
四、死锁
// DeadLockSample.cs
// 分析一下为什么会发生死锁?
using System;
using System.Threading;
public class Test
...{
static readonly object firstLock = new object();
static readonly object secondLock = new object();
static void Main()
...{
new Thread(new ThreadStart(ThreadJob)).Start();
// Wait until we're fairly sure the other thread
// has grabbed firstLock
Thread.Sleep(500);
Console.WriteLine ("Locking secondLock");
lock (secondLock)
...{
Console.WriteLine ("Locked secondLock");
Console.WriteLine ("Locking firstLock");
lock (firstLock)
...{
Console.WriteLine ("Locked firstLock");
}
Console.WriteLine ("Released firstLock");
}
Console.WriteLine("Released secondLock");
}
static void ThreadJob()
...{
Console.WriteLine (" Locking firstLock");
lock (firstLock)
...{
Console.WriteLine(" Locked firstLock");
// Wait until we're fairly sure the first thread
// has grabbed secondLock
Thread.Sleep(1000);
Console.WriteLine(" Locking secondLock");
lock (secondLock)
...{
Console.WriteLine(" Locked secondLock");
}
Console.WriteLine (" Released secondLock");
}
Console.WriteLine(" Released firstLock");
}
}
| Locking firstLock Locked firstLock Locking secondLock Locked secondLock Locking firstLock Locking secondLock |
因应之道,使用Queue和Monitor:
//QueueMonitorThread.cs
using System;
using System.Collections;
using System.Threading;
public class Test
...{
static ProducerConsumer queue;
static void Main()
...{
queue = new ProducerConsumer();
new Thread(new ThreadStart(ConsumerJob)).Start();
Random rng = new Random(0);
for (int i=0; i < 10; i++)
...{
Console.WriteLine ("Producing {0}", i);
queue.Produce(i);
Thread.Sleep(rng.Next(1000));
}
}
static void ConsumerJob()
...{
// Make sure we get a different random seed from the
// first thread
Random rng = new Random(1);
// We happen to know we've only got 10
// items to receive
for (int i=0; i < 10; i++)
...{
object o = queue.Consume();
Console.WriteLine (" Consuming {0}", o);
Thread.Sleep(rng.Next(1000));
}
}
}
public class ProducerConsumer
...{
readonly object listLock = new object();
Queue queue = new Queue();
public void Produce(object o)
...{
lock (listLock)
...{
queue.Enqueue(o);
if (queue.Count==1)
...{
Monitor.Pulse(listLock);
}
}
}
public object Consume()
...{
lock (listLock)
...{
while (queue.Count==0)
...{
Monitor.Wait(listLock);
}
return queue.Dequeue();
}
}
}
| Producing 0 Consuming 0 Producing 1 Consuming 1 Producing 2 Consuming 2 Producing 3 Consuming 3 Producing 4 Producing 5 Consuming 4 Producing 6 Consuming 5 Consuming 6 Producing 7 Consuming 7 Producing 8 Consuming 8 Producing 9 Consuming 9 |

1234

被折叠的 条评论
为什么被折叠?



