1. 编写多线程程序应该以正确的方式编写,保持线程的“原子性”,避免死锁,同时避免造成执行时的不确定性。
2. 所谓“原子操作”,要么能完成它的全部步骤,要么将系统状态恢复初始状态的一个操作。
3. 线程中DoWork()方法可以没有参数,也可以有参数。
·当DoWork没有参数时,声明方式如下:
ThreadStart threadStart = new ThreadStart(DoWork);
Thread thread = new Thread(threadStart);
thread.Start();
·当DoWork含有参数时,声明方式如下:
Thread thread = new Thread(DoWork);
thread.Start(parameters);
parameters可以为object类型,如果需要传递多个参数可以构建结构体。
4. 线程池处理ThreadPool,使用方式如下:
ThreadPool.QueueUserWorkItem(DoWork,'.');//其中’.’为DoWork方法的参数
ThreadPool拥有了传递参数的优势。
5. 使用Monitor来同步:为了同步两个线程,防止它们同时执行特定的代码段,需要使用一个监视器(Monitor)来阻止第二个线程进入一个受保护的代码段,直到第一个线程退出那个代码段。为了标识受保护代码段的开始和结束为止,需要分别调用静态方法Monitor.Enter()he Monitor.Exit(),但在两个调用之间,所有代码都要用一个try/finally块包围起来,防止发生异常从而阻止其他线程。
6. 使用lock关键字锁定同步模式。
readonly static object _sync = new object();
static long _Count = 0;
lock (_sync)
{
_Count++;
}
_sync称为同步变量被声明为私有和只读。声明为只读时为了确保在Monitor.Enter()和Monitor.Exit()调用之间,其值不会发生改变。这是相当重要的一环,否则同步代码块的进出就会失去关联性。
同步对象不可以是值类型的。否则会报异常,编译不会出错。
7. System.Threading.Mutex和Monitor几乎完全一致。Mutex是一个跨进程的资源。Mutex可以限制应用程序,让它不能同时运行多个实例。像QQ影音,只能运行一个实例。
static void Main(string[] args)
{
bool firstApplicationInstance;
string mutexName = Assembly.GetEntryAssembly().FullName;
using (Mutex mutex = new Mutex(false, mutexName, out firstApplicationInstance))
{
if (!firstApplicationInstance)
{
Console.WriteLine("This application is already running!");
}
else
{
Console.WriteLine("ENTER To Shutdown");
Console.ReadKey();
}
}
}
8. 使用原子操作类:InterLock类。
已重载。 以原子操作的形式,添加两个整数并用两者的和替换第一个整数。 | ||
| 已重载。 比较两个值是否相等,如果相等,则替换其中一个值。 | |
| 已重载。 以原子操作的形式递减指定变量的值并存储结果。 | |
| 已重载。 以原子操作的形式将变量设置为指定的值。 | |
| 已重载。 以原子操作的形式递增指定变量的值并存储结果。 | |
| 返回一个以原子操作形式加载的 64 位值 |