線程同步,安全執行緒例子

來源:互聯網
上載者:User
namespace ConsoleApplication22
{
class Program
{

static void Main(string[] args)
{


Thread[] ts = new Thread[30];
TestDemo td = new TestDemo();
int i;
for (i = 0; i < 30; i++)
{
ts[i] = new Thread(td.Test1);

ts[i].Start();
}



while (true)
{
bool flag = td.Test2();

if (flag)
break;
}

Console.ReadKey();
}



}


public class TestDemo
{
private Hashtable sh = new Hashtable();
private static object SynLock = new object();
int i = 0;

public void Test1()
{

lock (SynLock)
{

++i;
Thread.Sleep(1000);
System.Diagnostics.Debug.WriteLine(i+"roy");
sh.Add(i, i);
}


}

public bool Test2()
{
if (i != 30 && !sh.ContainsKey(30))
return false;

lock (SynLock)
{
foreach (DictionaryEntry de in sh)
{
Console.WriteLine("..............."+de.Key.ToString()+"................"+de.Value.ToString());
}

return true;
}
}
}
}
鎖定保護靜態成員,一般用typeof(類名)View Code

View Code

  internal class Account
{
int balance;
Random r = new Random();
// private static object synLock = new object();

internal Account(int initial)
{
balance = initial;
}

internal int Withdraw(int amount)
{

if (balance < 0)
{
//如果balance小於0則拋出異常
throw new Exception("Negative Balance");
}
//下面的代碼保證在當前線程修改balance的值完成之前
//不會有其他線程也執行這段代碼來修改balance的值
//因此,balance的值是不可能小於0 的
System.Diagnostics.Debug.WriteLine("Current Thread:" + Thread.CurrentThread.Name);
// Console.WriteLine("Current Thread:" + Thread.CurrentThread.Name);
//如果沒有lock關鍵字的保護,那麼可能在執行完if的條件判斷之後
//另外一個線程卻執行了balance=balance-amount修改了balance的值
//而這個修改對這個線程是不可見的,所以可能導致這時if的條件已經不成立了
//但是,這個線程卻繼續執行balance=balance-amount,所以導致balance可能小於0
if (balance >= amount)
{
// Thread.Sleep(5);
balance = balance - amount;
return amount;
}
else
{
return 0; // transaction rejected
}

}
TraceSource ts = new TraceSource("GetOMLogSource");
internal void DoTransactions()
{

lock (this)
{
// System.Diagnostics.Debug.WriteLine("Current Thread:" + Thread.CurrentThread.Name);

for (int i = 0; i < 100; i++)
Withdraw(r.Next(-50, 100));
}
}
}



class Program
{
static internal Thread[] threads = new Thread[10];
public static void Main()
{
Account acc = new Account(0);
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].Name = i.ToString();
for (int i = 0; i < 10; i++)
threads[i].Start();
Console.ReadLine();
}

}

鎖定保護執行個體成員,一般用this

安全執行緒: 顧名思義    就是  利用線程的同步技術,讓多個線程 安全地 訪問同一個資源(比如一個靜態全域變數,靜態全域集合等)

以下這些我經過單步調試,Trace日誌跟蹤,VS壓力測試工具做並發測試得出來的正確結論!一直有個關於同時保證安全執行緒和並發效能的博弈。做了下相關研究得出了幾種處理方式:安全執行緒,讓多個安全執行緒地訪問同一共用資源。通常都會用各種鎖來保證線程同步使共用資源不會發生意外的邏輯錯誤或異常。但是加了鎖以後,你系統中要讀取共用資源的線程只能等待,因為鎖使你的系統完全沒有並發性,這個在多用戶端對一個伺服器的正式系統正使用者體驗出奇的差。  我這裡就2個項目情境說說我的解決方式:(1)對於即時性不是非常高的系統,我們可以複製一個共用資源對象的副本,對副本做了所有相關業務操作以後,才真正鎖定共用資源,然後把副本對象的地址賦給共用資源,這樣就做到了儘可能的極少時間鎖定共用資源,提高了程式的並發性也保證了線程的安全。比如共用資源是服務端程式的一個dataset,N個用戶端程式通過遠程調用可以寫這個dataset,也要求讀這個dataset,當一個用戶端要求修改這個dataset的時候,我通常會產生一個這個dataset的一個副本進行操作,操作完成以後鎖定共用資源dataset把引用地址賦給它,這樣其他要求讀這個共用資源的用戶端不會有阻塞。 (2)對於即時性要求非常高的系統比如IM系統,我會採取讀寫鎖來處理這個問題,讀寫鎖可以保證擷取多個讀鎖,但只能擷取一個更新鎖定或寫鎖(排他的)。舉個例子再一個原子操作裡將讀鎖定擴大為寫鎖是很有用的,例如,假設你想要再一個list 裡面寫一些不存在的項的時候, 你可能會執行下面的一些步驟:1擷取一個讀鎖。2測試,如果要寫的東西在列表中,那麼釋放鎖,然後返回。3釋放讀鎖。4擷取一個寫鎖5添加項,寫東西,6釋放寫鎖。問題是:在第三步和第四步之間,可能有另一個線程修改了列表。一個可更新鎖定除了它可以在一個原子操作中變成寫鎖外很像一個讀鎖,你可以這樣使用它:1調用EnterUpgradeableReadLock 擷取可更新鎖定。2執行一些讀操作,例如判斷要寫的東西在不在List中。3調用EnterWriteLock , 這個方法會將可更新鎖定 升級為 寫鎖。4執行寫操作,5調用ExitWriteLock 方法,這個方法將寫鎖轉換回可更新鎖定。6繼續執行一些讀操作,或什麼都不做。6調用ExitUpgradeableReadLock 釋放可更新鎖定。7從調用者的角度來看,它很像一個嵌套/遞迴鎖,從功能上講,在第三步,ReaderWriterLockSlim 在一個原子操作裡面釋放讀鎖,然後擷取寫鎖。

根據錯誤提示,可知在調試器中運行應用程式時,如果不是控制項的建立者線程試圖調用該控制項時,則調試器會引發
InvalidOperationException,並提示訊息:“從不是建立控制項 Control Name
的線程訪問它。” 說白了,就是資源訪問的不一致性,控制項的調用者線程不是控制項的建立者線程,這是.net實現資源安全訪問機制的必然結果。訪問
Windows 表單控制項本質上不是安全執行緒的。如果多個線程同時操作某一控制項的狀態,則可能會迫使該控制項進入一種不一致的狀態。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.