多线程处理解决了吞吐量和响应速度的问题,但同时带来了资源共享的问题,如死锁和资源的争用。多线程特别适用于需要不同的资源的任务。为单个资源分配多个线程可能导致同步问题,这种情况下,线程可能会被频繁的阻止以等待其他线程。
同步是指多个线程之间存在着先后执行顺序的关联关系
当两个线程t1和t2有相同的优先级,并且同时在系统上运行,如果把时间片分配给t1使用,它在变量variable1写入某个值,但如果时间片用完时它任然没有写入,这时由于时间片已经分配给t2使用,而t2有恰尝试读取该变量的值,此时读出的就不再是正确的值了。这种情况下,如果使用同步仅允许一个线程使用variable1,在该线程完成对variable1的写入工作后再t2读取这个值,可以避免这种错误。
lock语句:
private Object lockedobj = new object();
lock (lockedobj)
{。。。}
lock关键字作用是:确保一个线程位于代码临界区时,另一个线程不再进临界区。
如果其他线程要进入锁定的代码段,则它将一直等待,直到锁定的对象被释放以后才能进入临界区。
lock关键字将代码标记为临界区,它的实现原理是首先锁定某一个私有的对象,然后执行代码段的语句,当代吗的语句执行完毕后,再解除该锁。
锁定的对象名一般声明为Object类型,注意不要声明为值类型。声明类型为 private
临界区的代码不宜过多。
1,先定义类
LockExample
public class LockExample
{
private Object lockedobj = new object();
int balance;
Form1 form1;
Random r = new Random();
public LockExample(int initial, Form1 form1)
{
this.form1 = form1;
this.balance = initial;
}
/// <summary>
/// 取款
/// </summary>
/// <param name="amount">取款金额</param>
/// <returns>取款</returns>
public int Withdraw(int amount)
{
if (balance < 0)
{
form1.AddListBoxItem("余额" + balance + "没有了");
}
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;
}
}
}
//自动取款
public void DoTransaction()
{
for (int i = 0; i < 10; i++)
{
Withdraw(r.Next(1, 100));
}
}
}
2、新建一个窗体
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
Thread[] threads = new Thread[10];
LockExample lockex=new LockExample (1000,this );
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(lockex.DoTransaction);
t.Name = "线程" + i;
threads = t;
}
for (int i = 0; i < 10; i++)
{
threads.Start();
}
}
public delegate void AddListBoxItemDelegate(string str);
public void AddListBoxItem(string str)
{
if (this.listBox1.InvokeRequired)
{
AddListBoxItemDelegate d = AddListBoxItem;
listBox1.Invoke(d, str);
}
else
{
listBox1.Items.Add(str);
}
}
}
结果为:
|