中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > .NET > 临时文章
使用lock确保线程安全
作者:未知 时间:2004-11-14 12:12 出处:Blog 责编:chinaitpower
              摘要:暂无

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

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;
        }
}



关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有