1. 程式人生 > >C#關於多執行緒及執行緒同步 lock鎖的應用

C#關於多執行緒及執行緒同步 lock鎖的應用

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinLock
{
    public partial
class Form1 : Form { public Form1() { InitializeComponent(); } private void btn_Start_Click(object sender, EventArgs e) { listBox1.Items.Clear(); Thread[] threads = new Thread[10];//使用new關鍵字在堆裡建立物件,其生命期相當於全域性變數,但訪問的時候與普通變數一樣
Account acc = new Account(1000, this); for (int i = 0; i < 10; i++) { Thread t = new Thread(acc.DoTransactions); t.Name = "執行緒" + i; threads[i] = t; } for (int i = 0; i < 10; i++) { threads[i].Start(); } }
delegate void AddListBoxItemDelegate(string str);//在類的內部也能宣告代理 public void AddListBoxItem(string str) { if (listBox1.InvokeRequired)//如果是跨執行緒訪問控制元件則為true { AddListBoxItemDelegate d = AddListBoxItem;//代理 listBox1.Invoke(d, str);//呼叫代理函式並傳遞引數 } else { listBox1.Items.Add(str);//不是跨執行緒訪問控制元件則直接訪問該控制元件 } } } }

account.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WinLock
{
    public class Account
    {
        private Object lockedObj = new Object();
        int balance;
        Random r = new Random();
        Form1 form1;
        public Account(int initial, Form1 form1)
        {
            this.form1 = form1;
            this.balance = initial;
        }
        /// <summary>
        /// 取款
        /// </summary>
        /// <param name="amount">取款金額</param>
        /// <returns>餘額</returns>
        private int Withdraw(int amount)
        {
            if (balance < 0)
            {
                form1.AddListBoxItem("餘額:" + balance + " 已經為負值了,還想取呵!");
            }

            //將lock (lockedObj)這句註釋掉,看看會發生什麼情況
            lock (lockedObj)
            {
                if (balance >= amount)
                {
                    string str = Thread.CurrentThread.Name + "取款---";
                    str += string.Format("取款前餘額:{0,-6}取款:{1,-6}", balance, amount);
                    balance = balance - amount;
                    str += "取款後餘額:" + balance;
                    form1.AddListBoxItem(str);
                    return amount;
                }
                else
                {
                    return 0;
                }
            }
        }
        /// <summary>自動取款</summary>
        public void DoTransactions()//Transaction--事務
        {
            for (int i = 0; i < 100; i++)
            {
                Withdraw(r.Next(1, 100));
            }
        }

    }
}

 

 

不加lock 會出現統一資源被多次利用的情況