使用lock确保线程安全

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

当多个线程同时访问共享区时,就会产生线程安全问题。

例如:

using System;

using System.Threading;

class Account

{

int balance;

Random r = new Random();

public Account(int initial)

{

balance = initial;

}

int Withdraw(int amount)

{

if (balance < 0)

{

throw new Exception("Negative Balance");

}

// Comment out the next line to see the effect of leaving out

// the lock keyword:

if (balance >= amount)

{

Console.WriteLine("Balance before Withdrawal : " + balance);

Console.WriteLine("Amount to Withdraw : -" + amount);

balance = balance - amount;

Console.WriteLine("Balance after Withdrawal : " + balance);

return amount;

}

else

{

return 0;

}

}

public void DoTransactions()

{

for (int i = 0; i < 100; i++)

{

Withdraw(r.Next(1, 100));

}

}

}

class Test

{

public static void Main()

{

Thread[] threads = new Thread[10]; //10个线程访问共享区

Account acc = new Account (1000);

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

{

Thread t = new Thread(new ThreadStart(acc.DoTransactions));

threads[i] = t;

}

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

{

threads[i].Start();

}

}

}

程序改为,即可:

using System;

using System.Threading;

class Account

{

int balance;

Random r = new Random();

public Account(int initial)

{

balance = initial;

}

int Withdraw(int amount)

{

// This condition will never be true unless the lock statement

// is commented out:

if (balance < 0)

{

throw new Exception("Negative Balance");

}

// Comment out the next line to see the effect of leaving out

// the lock keyword:

lock (this)

{

if (balance >= amount)

{

Console.WriteLine("Balance before Withdrawal : " + balance);

Console.WriteLine("Amount to Withdraw : -" + amount);

balance = balance - amount;

Console.WriteLine("Balance after Withdrawal : " + balance);

return amount;

}

else

{

return 0; // transaction rejected

}

}

}

public void DoTransactions()

{

for (int i = 0; i < 100; i++)

{

Withdraw(r.Next(1, 100));

}

}

}

class Test

{

public static void Main()

{

Thread[] threads = new Thread[10];

Account acc = new Account (1000);

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

{

Thread t = new Thread(new ThreadStart(acc.DoTransactions));

threads[i] = t;

}

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

{

threads[i].Start();

}

}

}

这个就像版本控制中的原理。lock也可以解决singleton中的多线程不安全问题。

这里给出一个懒人模式的singleton的线程安全代码:

public sealed class SingletonTest

{

private SingletonTest()

{

//TODO:一些初始化

}

//m_instance申明为volatile则,当变量申明完成后才能访问。

private static volatile SingletonTest m_instance = null;

private static Object sync = new Object();

public static SingletonTest createInstance()

{

if(m_instance == null)

{

lock(sync)

{

m_instance = new SingletonTest();

}

}

return m_instance;

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航