如:
class ThreadTest
{
//全局变量
int i;
static void Main()
{
ThreadTest tt = new ThreadTest(); // 创建一个ThreadTest类的实例
new Thread (tt.Go).Start();
tt.Go();
}
// Go方法属于ThreadTest的实例
void Go()
{
if (i==1) { ++i; Console.WriteLine (i); }
}
}
输出
2
新线程和主线程上调用了同一个实例的Go方法,所以变量i共享。
静态变量也可以被多线程共享
class ThreadTest
{
static int i; // 静态变量可以被线程共享
static void Main()
{
new Thread (Go).Start();
Go();
}
static void Go()
{
if (i==1) { ++i; Console.WriteLine (i); }
}
}
输出
2
如果将Go方法的代码位置互换
static void Go()
{
if (i==1) { Console.WriteLine (i);++i;}
}
输出
1 1(有时输出一个,有时输出两个)
如果新线程在Write之后,done=true之前,主线程也执行到了write那么就会有两个done。
不同线程在读写共享字段时会出现不可控的输出,这就是多线程的线程安全问题。
解决方法: 使用排它锁来解决这个问题--lock
class ThreadSafe
{
static bool done;
static readonly object locker = new object();
static void Main()
{
new Thread (Go).Start();
Go();
}
static void Go()
{
//使用lock,确保一次只有一个线程执行该代码
lock (locker)
{
if (!done) { Console.WriteLine ("Done"); done = true; }
}
}
}
当多个线程都在争取这个排它锁时,一个线程获取该锁,其他线程会处于blocked状态(该状态时不消耗cpu),等待另一个线程释放锁时,捕获该锁。这就保证了一次
只有一个线程执行该代码。
Join和Sleep
Join可以实现暂停另一个线程,直到调用Join方法的线程结束。
static void Main()
{
Thread t = new Thread (Go);
t.Start();
t.Join();
Console.WriteLine ("Thread t has ended!");
}
static void Go()
{
for (int i = 0; i < 1000; i++) Console.Write ("y");
}
输出
yyyyyy..... Thread t has ended!
线程t调用Join方法,阻塞主线程,直到t线程执行结束,再执行主线程。
Sleep:暂停该线程一段时间
Thread.Sleep (TimeSpan.FromHours (1)); // 暂停一个小时 Thread.Sleep (500); // 暂停500毫秒 Join是暂停别的线程,Sleep是暂停自己线程。
上面的例子是使用Thread类的构造函数,给构造函数传入一个ThreadStart委托。来实现的。
public delegate void ThreadStart();
然后调用Start方法,来执行该线程。委托执行完该线程也结束。
如:
class ThreadTest
{
static void Main()
{
Thread t = new Thread (new ThreadStart (Go));
t.Start(); // 执行Go方法
Go(); // 同时在主线程上执行Go方法
}
static void Go()
{
Console.WriteLine ("hello!");
}
}










