当前位置:编程学习 > C#/ASP.NET >>

C# 线程同步问题

  在现实生活中,假设有一个生产者和一个消费者。生产者生成货物存储在货物栈中,消费者从货物栈中取货物。假设生产者的生成速度超过消费者消费速度,则货物栈会在某一个时刻被装满,此时生产者若继续生产会导致两种情况:货物栈溢出;货物栈中已有货物被替换。假设消费者的消费速度超过生产者的生产速度,则货物栈会在某一个时刻被取空,此时消费者若继续消费会导致消费者得到的货物为空。实现生产者消费者同步的目的在于使得生产者按顺序生产,消费者按顺序消费,当生产速度过快时,暂停生产;当消费速度过快时,暂停消费。生产者和消费者的行为需要一个管理员来控制。
 
        使用两个线程来分别模拟生产者和消费者。使用 Monitor 来模拟管理员。管理员在生产过剩时告诉生产者暂停生产,消费过剩时告诉消费者暂停消费。
 
 
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading;  
  
namespace MultiThread  
{  
    class Problem  
    {  
        static int[] buffers=new int[3];  
        static int readLocation=0;  
        static int writeLocation = 0;  
        static object locker=new object();  
        static int blankCount = 3;  
  
  
        private int Buffer   
        {  
            get   
            {  
                lock (locker)  
                {  
                    if (blankCount >= 3)  
                    {  
                        Console.WriteLine("buffers are all empty now! Consumer waits!");  
                        Monitor.Wait(locker);  
                    }  
                    readLocation = readLocation % 3;  
                    int buffer = buffers[readLocation];  
                    buffers[readLocation] = 0;  
                    readLocation++;  
                    blankCount++;  
                    Monitor.Pulse(locker);  
                    return buffer;  
                }  
            }  
            set  
            {  
                lock (locker)  
                {  
                    if (blankCount <= 0)  
                    {  
                        Console.WriteLine("buffers are all full now! Producer waits!");  
                        Monitor.Wait(locker);   
                    }  
                    writeLocation = writeLocation % 3;  
                    buffers[writeLocation] = value;  
                    writeLocation++;  
                    blankCount--;  
                    Monitor.Pulse(locker);  
                }  
            }  
        }  
  
        void Produce()  
        {  
              
            for (int i = 0; i < 11; i++)  
            {  
                  
                  
                lock (locker)  
                {  
                    this.Buffer = i+1;  
                    Console.WriteLine("Produer has produce a " + (i+1) + " in buffers");  
                    Thread.Sleep(1000);  
                }  
                  
            }  
        }  
  
        void Consume()  
        {  
              
            for (int i = 0; i < 11; i++)  
            {  
                  
                  
                lock (locker)  
                {  
                    Console.WriteLine("Consumber has consume a " + this.Buffer + " from buffers");  
                    Thread.Sleep(1000);  
                }  
                  
            }  
        }  
        static void Main(string[] args)  
        {  
            Problem p = new Problem();  
            Thread producer = new Thread(p.Produce);  
            Thread consumer = new Thread(p.Consume);  
            producer.Name = "producer";  
            producer.Start();  
            consumer.Name = "consumer";  
            consumer.Start();  
            Console.ReadKey();  
        }  
    }  
}  

 

 
          锁对象并不保证线程间会同步。生产者消费者都拥有锁,锁就没有作用,线程执行时会忽略锁的存在继续执行被锁住的代码。只有管理员通过这个锁来通知生产者和消费者时,这个锁才会起到阻止线程执行的作用。锁的目的只是保证这个代码块中的变量的值是最新的,但不保证别的线程不会去修改这个变量。锁可以是任意对象,但要保证消费和生产这一对操作所使用的锁对象是同一个对象。
1. Memory barriers
 
http://stackoverflow.com/questions/6581848/memory-barrier-generators
 
2. Threading in C#
补充:软件开发 , C# ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,