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 会出现统一资源被多次利用的情况

猜你喜欢

转载自www.cnblogs.com/youmingkuang/p/9984461.html