| 多线程处理解决了吞吐量和响应速度的问题,但同时带来了资源共享的问题,如死锁和资源的争用。多线程特别适用于需要不同的资源的任务。为单个资源分配多个线程可能导致同步问题,这种情况下,线程可能会被频繁的阻止以等待其他线程。 同步是指多个线程之间存在着先后执行顺序的关联关系
 
 当两个线程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);
 }
 }
 }
 结果为:
   |