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 會出現統一資源被多次利用的情況

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM