熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C#多線程中lock的用法

2013-11-13 12:13:21  來源: .NET編程 

  經常碰到同時需要對某個數據進行操作或者對某個文件進行讀寫操作對於這些操作我們以前往往不能很好的進行處理自從C#語言中引入了lock這個關鍵字以上問題就比較容易予以解決了下面就是一段簡單的代碼

public class AccessControl()
  {
  private static object privateObjectLock = new object();
  public static AccessResult()
   {
  lock(privateObjectLock)
  {
  //數據操作語句
  }
  }
  }

  在做郵箱接收網關的時候遇到了以下的需求要求為每一個郵箱開啟一個接收線程從POP服務器上收取然後將郵件存放到統一的FTP服務器上要求郵件按收接順充從開始順充編號

  我實現的方法為為每個郵箱new出實例然後分別賦給POP郵箱地址用戶名密碼等參數這裡涉及到一個編號同步的問題因為每個接收郵件的線程都是自己執行所以取得編號並且遞增這個動作是互斥的

  以一個靜態變量表示編號如下

  class EmailInfo
  {
  public static int CurrentNumber;
  }

  那在當前線程取得這個步驟為

CurrentNumber=++EmailInfoCurrentNumber;

  雖然此為一句但在計算機運行時卻分為多步如下

  EmialInfoCurrentNumber加EmailInfoCurrentNumber返回值給_CurrentNumber也許線程執行了EmailInfoCurrentNumber加 的操作但還沒有取得返回值此時線程又執行了EmailInfoCurrentNumber加的操作然後又線程線程取得了返回值就是一樣的這樣就失去了按順序遞增的作用

  此時查找了網上有關線程同步的方法其實用lock語句鎖住遞增的那一段即可而介紹的相關用法為

  lock(this)
  {
  _CurrentNumber=++EmailInfoCurrentNumber;
  }

  本以為這樣就可以成功誰知道還是無效反復查找才發現沒弄清楚lock的用法因為網上所講的資料舉的例子比較簡單是直接new 出一個對像然後為對像的一個函數創建了多個線程運行所以它的同步只要lock住this即它自己就行了因為此時只有一個實例在運而我是new 出了多個對像lock住每個自己的實例所以當然無效

  所以自然想了一個解決方法就lock住相同的一個實例就行了

  因為我每個郵件接收線程的參數都是不同的所以還是new出幾個實像但lock的方法改為如下

  先為EmailInfo加一個靜態變量

  class EmailInfo
  {
  public static object syncRoot = new object();
  public static int CurrentNumber;
  }

  然後lock改為

  lock(EmailInfosyncRoot)
  {
  _CurrentNumber=++EmailInfoCurrentNumber;
  }

  即可實現想要的效果了


From:http://tw.wingwit.com/Article/program/net/201311/15429.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.