C# 多个线程调用一个方法并访问的同一个全局变量。模拟抢票软件

项目场景:

使用多线程访问全局变量,模拟抢票软件


实现过程:

1.num是一个全局任务,开启三个线程同时访问。模拟抢票 。 2.重点在于把总任务在子线程访问的时候先拿一个临时变量先取出来。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 总的数量
        /// </summary>
        public int num = 0;
        public int cycle = 0;
        public bool Threadflag = false;
        /// <summary>
        /// 定义一个委托类型
        /// </summary>
        public delegate void mydelegate1();
        /// <summary>
        /// 定义一个委托变量
        /// </summary>
        mydelegate1 MonitorHandle = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            //绑定一个方法给monitorhandle(监控所有线程用)
            MonitorHandle = new mydelegate1(MonitorThread);
           
        }
        private object oj = new object();

        private void test1(object flag)
        {

            for (int j = 0; j <= cycle; j++)
            {
                int temp = 0;
                try
                {
                    //这里需要访问全局变量,加lock
                    lock (oj)
                    {
                        temp = num;
                        num--;
                    }

                    /* i = num*/
                    Thread.Sleep(500); ;
                    if (temp < 1)
                    {

                        Threadflag = true;
                        return;
                    }
                    else
                    {
                        //BeginInvoke异步方法向textbox里面添加log
                        this.textBox1.BeginInvoke(new Action(() =>
                        {
                            this.textBox1.AppendText("我是Thread:" + flag.ToString() + ">>>" + "剩余票数" + temp.ToString() + Environment.NewLine);
                        }));
                        //if (OnUpdataUI != null)
                        //    OnUpdataUI((int)flag, temp);

                    }

                }
                catch (Exception e)
                { }
            }

        }


        Thread td1 = null;
        Thread td2 = null;
        Thread td3 = null;
        private void button1_Click(object sender, EventArgs e)
        {
            Threadflag = false;
            num = 10;
            cycle = num;
            this.button1.Enabled = false;
            this.textBox1.Clear();
            Thread td = new Thread(ExcuThread);
            td.IsBackground = true;
            td.Start();
            //执行监控方法         
            if (MonitorHandle != null)
                MonitorHandle();

        }
        private void ExcuThread()
        {
            td1 = new Thread(test1);
            td2 = new Thread(test1);
            td3 = new Thread(test1);
            td1.Name = "Thread 1";
            td2.Name = "Thread 2";
            td3.Name = "Thread 3";
            td1.IsBackground = true;
            td2.IsBackground = true;
            td3.IsBackground = true;
            td1.Start(1);
            td2.Start(2);
            td3.Start(3);

        }
        /// <summary>
        /// 监控线程是否结束
        /// </summary>
        private void MonitorThread()
        {
            DateTime dt1 = DateTime.Now;
            while (true)
            {
                Application.DoEvents();
                //判断当前所有的线程是否停止
                if (Threadflag)
                {
                    Threadflag = false;
                    DateTime dt2 = DateTime.Now;
                    //计算总的行数和耗时
                    this.label1.Text = "总行数:" + this.textBox1.Lines.GetUpperBound(0).ToString() + " 耗时:" + ExecDateDiff(dt1, dt2) + "s";
                    this.button1.Enabled = true;                    
                    break;
                }
            }
        }
        /// <summary>
        /// 计算时间差值
        /// </summary>
        /// <param name="dateBegin">开始时间</param>
        /// <param name="dateEnd">结束时间</param>
        /// <returns></returns>
        private string ExecDateDiff(DateTime dateBegin, DateTime dateEnd)
        {
            TimeSpan ts1 = new TimeSpan(dateBegin.Ticks);
            TimeSpan ts2 = new TimeSpan(dateEnd.Ticks);
            TimeSpan ts3 = ts1.Subtract(ts2).Duration();            //你想转的格式
            return (ts3.TotalMilliseconds / 1000).ToString();
        }
    }
}



在这里插入图片描述

感兴趣的同学可以直接复制代码跑跑。

  • 10
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值