Parallel.For很明顯跟上一篇Parallel.Foreach是差不多的東西
所以我們再加上 Lock 來讓情況變有趣些
假設我戶頭共有100塊 每次領錢都領10塊
領到戶頭歸零就不能再領了
單執行緒的情況大家都知道該怎麼寫
但今天如果是平行處理 一切同時發生 那我怎控制程式不出錯呢?
由此可知
1. 單執行緒肯定沒問題
2. 平行處理我無法預估誰會先領錢、或也許是一起在領錢,故我們得對領錢這個動作上鎖
=> 一次只能有一個人在領錢
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
/// <summary>
/// 示範 Parallel.For + Lock
/// </summary>
class Program
{
static void Main(string[] args)
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("【第" + i.ToString() + "回合】共有 100 塊, 每次領 10 塊");
Single();
Multi();
Console.WriteLine();
}
Console.Read();
}
private static void Single()
{
ATM myDb = new ATM();
Console.WriteLine("單執行緒");
for (int i = 1; i < 15; i++)
{
Console.WriteLine("序號" + i.ToString("00") + ":" + myDb.Withdraw());
}
Console.WriteLine();
}
private static void Multi()
{
ATM myATM = new ATM();
Console.WriteLine("平行處理");
Parallel.For(1, 15, i =>
{
Thread.Sleep(300);
Console.WriteLine("序號" + i.ToString("00") + ":" + myATM.Withdraw());
});
Console.WriteLine();
}
}
class ATM
{
private Object _lock = new Object();
int money = 100;
public string Withdraw()
{
if (NoMoney()) return "錢不夠";
//表示會有很多人在這等待進入lock區 (但同時只能一人進入)
lock (_lock)
{
//也許他通過驗證'錢不夠' 已經是一小時前了
//但在門口排隊一小時才輪到他進來
//所以你如何確定現在餘額還夠呢?
if (NoMoney()) return "錢不夠";
money -= 10;
return "還剩" + money;
}
}
private bool NoMoney()
{
return (money - 10) < 0;
}
}
}
提醒大家一個重點
我們只能確認進入Lock以後一定是一次一個
其他地方發生過的事都不算數
故你在其他地方做過什麼 你得再Lock區內再做一次
如同註解寫的
//也許他通過驗證'錢不夠' 已經是一小時前了
//但在門口排隊一小時才輪到他進來
//所以你如何確定現在餘額還夠呢?