多线程的一些注意点

Thread.Sleep()方法: Sleep是把当前线程挂起多少毫秒。当到了挂起时间是,不意味着当前线程会立即被唤醒。

举个例子:

static object lockObj = new object(); 
static void A() 
{ lock (lockObj) //进入就绪队列
       { 
         Thread.Sleep(1000); Monitor.Pulse(lockObj); 
         Monitor.Wait(lockObj); //自我流放到等待队列 
        }
       Console.WriteLine("A exit...");
 }
static void B() 
{ 
    Thread.Sleep(500);
    lock (lockObj) //进入就绪队列
          { 
             Monitor.Pulse(lockObj);
          } 
   Console.WriteLine("B exit..."); 
} 
static void C() 
{ 
   Thread.Sleep(750); 
   lock (lockObj) //进入就绪队列 
       {
 
       } 
  Console.WriteLine("C exit..."); 
} 
static void Main(string[] args) 
{ 
new Thread(A).Start();
 new Thread(B).Start(); 
new Thread(C).Start(); 
}

 这个程序输出的顺序:不一定是B,C,A。而是三个顺序都有可能。

第一次我看到的时候,以为输出的顺序一定是B,C,A当时没有理解Sleep的用法。

要想输出的顺序一定是B,C,A的话,可以使用ManualResetEvent,或者AutoResetEvent。

这两个类是用来阻塞线程的,当你需要唤醒的时候,可以通过Set()方法来唤醒阻塞的线程。

ManualResetEvent 当多个线程调用ManualResetEvent.WaitOne()方法以后,调用ManualResetEvent.Set()以后是所有的线程都不阻塞了,并且以后都不阻塞。

AutoResetEvent 多个线程调用waitOne阻塞以后,调用Set方法以后是随机选择一个线程进行释放,并且释放的线程通过一次以后又是阻塞的状态。 下面是利用ManualResetEvent来实现输出的价格必须是B,C,A的顺序。

static void Main(string[] args) 
{ 
Thread t1 = new Thread(A); 
Thread t2 = new Thread(B); 
t2.Start(); 
Thread t3 = new Thread(C); 
t2.Join(); t3.Start(); t3.Join(); 
t1.Start(); t1.Join(); 
Console.WriteLine("cs"); 
Console.ReadKey(); 
} 

 

线程的调度: Windows下的调度是根据每个线程的优先级进行调度的,优先级跟线程的优先级,饥饿度,占用时间有关系的。

Sleep的意思就是告诉调度器我在这段时间内不会参与竞争资源的调度,当调用Sleep(0)时,会立即进行一个线程优先级的计算,挑选出一个优先级高的线程占用CPU。

Linux下面是根据时间段来的,每个线程执行一段时间,如果在这时间执行完了,就可以提前退出。

posted @ 2017-04-13 11:23  大洒家2浪  阅读(231)  评论(0)    收藏  举报