如何让两个不同的线程同时写入一个变量?C#
我正在尝试建立一个ATM,我需要展示一个数据竞赛的例子 为此,我需要两个线程同时写入一个变量(我想) 当点击“取出10$”按钮时,线程会写入这个变量,但我不能同时点击两个按钮,这意味着我不能真正显示数据。下面是按钮单击事件的代码如何让两个不同的线程同时写入一个变量?C#,c#,multithreading,C#,Multithreading,我正在尝试建立一个ATM,我需要展示一个数据竞赛的例子 为此,我需要两个线程同时写入一个变量(我想) 当点击“取出10$”按钮时,线程会写入这个变量,但我不能同时点击两个按钮,这意味着我不能真正显示数据。下面是按钮单击事件的代码 private void button1_Click(object sender, EventArgs e) { if (Form1.currAcc.getBalance() < 10) { System.Windows.Forms.Message
private void button1_Click(object sender, EventArgs e)
{
if (Form1.currAcc.getBalance() < 10)
{
System.Windows.Forms.MessageBox.Show("Insuficient Funds");
this.Close();
}
else
{
Form1.currAcc.setBalance(Form1.currAcc.getBalance() - 10);
System.Windows.Forms.MessageBox.Show("Succesfully withdrawn 10$");
this.Close();
}
}
private void按钮1\u单击(对象发送者,事件参数e)
{
if(Form1.currAcc.getBalance()<10)
{
System.Windows.Forms.MessageBox.Show(“资金不足”);
这个。关闭();
}
其他的
{
Form1.currAcc.setBalance(Form1.currAcc.getBalance()-10);
System.Windows.Forms.MessageBox.Show(“成功提取10美元”);
这个。关闭();
}
}
编辑:这给了我一场数据竞赛:
private void button1_Click(object sender, EventArgs e)
{
if (Form1.currAcc.getBalance() < 10)
{
System.Windows.Forms.MessageBox.Show("Insuficient Funds");
this.Close();
}
else
{
currentBalance = Form1.currAcc.getBalance();
Form5.timerStatus++;
if (Form5.timerStatus == 1)
{
Thread.Sleep(3000);
Form1.currAcc.setBalance(currentBalance - 10);
System.Windows.Forms.MessageBox.Show("Succesfully withdrawn 10$");
}
else{
Form1.currAcc.setBalance(currentBalance - 10);
System.Windows.Forms.MessageBox.Show("Succesfully withdrawn 10$");
Form5.timerStatus = 0;
}
this.Close();
}
}
private void按钮1\u单击(对象发送者,事件参数e)
{
if(Form1.currAcc.getBalance()<10)
{
System.Windows.Forms.MessageBox.Show(“资金不足”);
这个。关闭();
}
其他的
{
currentBalance=Form1.currencc.getBalance();
Form5.timerStatus++;
如果(Form5.timerStatus==1)
{
睡眠(3000);
表1.当前余额(当前余额-10);
System.Windows.Forms.MessageBox.Show(“成功提取10美元”);
}
否则{
表1.当前余额(当前余额-10);
System.Windows.Forms.MessageBox.Show(“成功提取10美元”);
Form5.timerStatus=0;
}
这个。关闭();
}
}
这相当简单:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main()
{
for (int i = 0; i < 4; ++i)
Task.Run(() => withdraw(800m));
Thread.Sleep(1000);
// Balance should be 200 unless a race condition occured.
Console.WriteLine(balance);
}
static void withdraw(decimal amount)
{
if (balance >= amount)
balance -= amount;
}
static decimal balance = 1000.0m;
}
}
这相当容易:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main()
{
for (int i = 0; i < 4; ++i)
Task.Run(() => withdraw(800m));
Thread.Sleep(1000);
// Balance should be 200 unless a race condition occured.
Console.WriteLine(balance);
}
static void withdraw(decimal amount)
{
if (balance >= amount)
balance -= amount;
}
static decimal balance = 1000.0m;
}
}
演示竞争条件的最简单方法是使用并行库,因为它将同时启动多个线程。下面的代码很好地演示了这一点
Parallel.For(1, 11, r =>
{
Console.WriteLine($"Thread{r}: Balance: ${_balance}");
if (_balance < r)
{
Console.WriteLine($"Thread{r}: Insufficient funds ${_balance}");
return;
}
_balance -= r;
Console.WriteLine($"Thread{r}: Withdraw ${r}. New Balance is ${_balance}");
});
Console.WriteLine("Press any key to exit");
Console.Read();
Parallel.For(1,11,r=>
{
WriteLine($“Thread{r}:Balance:${u Balance}”);
如果(_余额
它将生成这样的输出
线程1:余额:20美元线程1:提取1美元。新余额为19美元
线程6:余额:$19
线程2:余额:20美元
线程3:余额:20美元
线程4:余额:20美元
线程5:余额:$19
线程8:余额:4美元
线程8:资金不足$4
线程9:余额:4美元
线程9:资金不足4美元
线程10:余额:4美元
线程10:资金不足$4
线程4:提取4美元。新余额为4美元
线程5:资金不足$4
线程6:提取6美元。新余额为13美元
线程2:提取2美元。新余额为11美元
线程7:余额:11美元
线程7:资金不足4美元
线程3:提取3美元。新余额为8美元
按任意键退出
这表明,螺纹最初看到的平衡和实际减去的平衡不一样,例如,线程5在启动时看到了$20,但当它试图提取$5时,它得到了资金不足的响应证明竞争条件的最简单方法是使用并行库,因为它将同时启动多个线程。下面的代码很好地演示了这一点
Parallel.For(1, 11, r =>
{
Console.WriteLine($"Thread{r}: Balance: ${_balance}");
if (_balance < r)
{
Console.WriteLine($"Thread{r}: Insufficient funds ${_balance}");
return;
}
_balance -= r;
Console.WriteLine($"Thread{r}: Withdraw ${r}. New Balance is ${_balance}");
});
Console.WriteLine("Press any key to exit");
Console.Read();
Parallel.For(1,11,r=>
{
WriteLine($“Thread{r}:Balance:${u Balance}”);
如果(_余额
它将生成这样的输出
线程1:余额:20美元线程1:提取1美元。新余额为19美元
线程6:余额:$19
线程2:余额:20美元
线程3:余额:20美元
线程4:余额:20美元
线程5:余额:$19
线程8:余额:4美元
线程8:资金不足$4
线程9:余额:4美元
线程9:资金不足4美元
线程10:余额:4美元
线程10:资金不足$4
线程4:提取4美元。新余额为4美元
线程5:资金不足$4
线程6:提取6美元。新余额为13美元
线程2:提取2美元。新余额为11美元
线程7:余额:11美元
线程7:资金不足4美元
线程3:提取3美元。新余额为8美元
按任意键退出 这表明线程最初看到的余额和实际减去的余额不一样,例如,线程5在开始时看到了20美元,但当它试图提取5美元时,得到了资金不足的响应,“代码”回答都是好的,但我认为有一个概念上的东西值得指出:多线程在同一时间点做某事并不重要 这些问题的本质是:由于缺少“同步”,当这些线程进行更新时无法预测。因此,根据最先进入的线程,最终会得到不同的结果 因此,让多个线程并行增加一个计数器已经足够了——如果以“非同步”的方式增加计数器,最终结果将(很可能)与预期值不匹配 意思:简单的事情,比如
fetch the current counter
do something else that takes a bit of time
write "counter+1" to counter
这已经足够好了。这些书写是否及时“接近”并不重要;唯一需要的是