C#多线程学习笔记(三)

  1. 云栖社区>
  2. 博客>
  3. 正文

C#多线程学习笔记(三)

天地弦 2006-11-22 21:33:00 浏览681
展开阅读全文
刚刚把前两天的笔记整理完了,发现做笔记可以加深印象。要坚持做下去,可以学到一些细节的东西。

a.今天学到一个非常试用的lock
  语法:
   lock(expression) statement_block
   expression代表你希望跟踪的对象,通常是对象引用。一般地,如果你想保护一个类的实例,你可以使用this;如果你希望保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以了。而statement_block就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。
img_a6339ee3e57d1d52bc7d02b338e15a60.gifusing System;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Collections.Generic;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Text;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Threading;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
namespace LockThread
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif    
internal class Account
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif        
int balance;
img_33d02437d135341f0800e3d415312ae8.gif        Random r 
= new Random();
img_33d02437d135341f0800e3d415312ae8.gif        
internal Account(int _initial)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            balance 
= _initial;
img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif        
internal int Withdraw(int _amount)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            
if(balance < 0)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                
//如果balance<0则抛出异常
img_33d02437d135341f0800e3d415312ae8.gif
                throw new Exception("Negative Balance");
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif            
//下面的代码保证在当前线程修改balance的值完成之前
img_33d02437d135341f0800e3d415312ae8.gif            
//不会有其他线程也执行这段代码来修改balance的值
img_33d02437d135341f0800e3d415312ae8.gif            
//因此,balance的值是不可能小于0的
img_33d02437d135341f0800e3d415312ae8.gif
            lock(this)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                Console.WriteLine(
"Current Thread:"+Thread.CurrentThread.Name);
img_33d02437d135341f0800e3d415312ae8.gif                
//如果没有lock关键字的保护,那么可能在执行完if的条件判断之后
img_33d02437d135341f0800e3d415312ae8.gif            
//另外一个线程却执行了balance=balance-amount修改了balance的值
img_33d02437d135341f0800e3d415312ae8.gif            
//而这个修改对这个线程是不可见的,所以可能导致这时if的条件已经不成立了
img_33d02437d135341f0800e3d415312ae8.gif            
//但是,这个线程却继续执行balance=balance-amount,所以导致balance可能小于0
img_33d02437d135341f0800e3d415312ae8.gif
                if(balance >= _amount)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                    Thread.Sleep(
5);
img_33d02437d135341f0800e3d415312ae8.gif                    balance 
= balance -_amount;
img_33d02437d135341f0800e3d415312ae8.gif                    
return _amount;
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                }
 elseimg_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                    
return 0;//处理事务被拒绝
img_105a1e124122b2abcee4ea8e9f5108f3.gif
                }

img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_33d02437d135341f0800e3d415312ae8.gif        
internal void DoTransactions()
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            
for(int i = 0;i<100; i++)
img_33d02437d135341f0800e3d415312ae8.gif                Withdraw(r.Next(
-50100));
img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_33d02437d135341f0800e3d415312ae8.gif
img_105a1e124122b2abcee4ea8e9f5108f3.gif  }

img_33d02437d135341f0800e3d415312ae8.gif 
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif    
class Program
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif        
static internal Thread[] threads = new Thread[10];
img_33d02437d135341f0800e3d415312ae8.gif        
static void Main(string[] args)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            Account acc 
= new Account(0);
img_33d02437d135341f0800e3d415312ae8.gif            
for (int i = 0; i < 10; i++)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                Thread t 
= new Thread(new ThreadStart(acc.DoTransactions));
img_33d02437d135341f0800e3d415312ae8.gif                t.Name 
= i.ToString();
img_33d02437d135341f0800e3d415312ae8.gif                threads[i] 
= t;
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            
for (int i = 0; i < 10; i++)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                threads[i].Start();
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif            Console.ReadLine();
img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_105a1e124122b2abcee4ea8e9f5108f3.gif    }

img_05dd8d549cff04457a6366b0a7c9352a.gif}

img_a6339ee3e57d1d52bc7d02b338e15a60.gif


b.还有一个Moniter对象是用来监视对象的,
......
Queue oQueue=new Queue();
......
Monitor.Enter(oQueue);
......//现在oQueue对象只能被当前线程操纵了
Monitor.Exit(oQueue);//释放锁

上面表示oQueue这个对象只有一个线程可以操纵,只有当Mointor.Exit才可以被其它线程所操纵

网友评论

登录后评论
0/500
评论
天地弦
+ 关注