zoukankan      html  css  js  c++  java
  • 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 会出现统一资源被多次利用的情况

  • 相关阅读:
    哈哈,拖了一天
    内置函数续
    内置函数2
    内置函数1
    内置函数补充
    生成器面试题
    字段值为null的处理
    oracle日期转换报ORA-01810: 格式代码出现两次 01810. 00000 -  "format code appears twice"
    通过sql脚本可以从数据库中查到数据,但是通过jdbc却获取不到
    java外部捕获了异常,但是并没有打印异常和将异常信息写入日志文件
  • 原文地址:https://www.cnblogs.com/youmingkuang/p/9984461.html
Copyright © 2011-2022 走看看