zoukankan      html  css  js  c++  java
  • c# 多线程排队队列实现的源码

    [csharp] view plaincopy
    1. using System;  
    2.   
    3. using System.Threading;  
    4.   
    5. using System.Collections;  
    6.   
    7. using System.Collections.Generic;  
    8.   
    9.   
    10. // 将线程同步事件封装在此类中,   
    11.   
    12. // 以便于将这些事件传递给 Consumer 和  
    13.   
    14. // Producer 类。  
    15.   
    16. public class SyncEvents  
    17.   
    18. {  
    19.   
    20.     public SyncEvents()  
    21.   
    22.     {  
    23.   
    24.         // AutoResetEvent 用于“新项”事件,因为  
    25.   
    26.         // 我们希望每当使用者线程响应此事件时,  
    27.   
    28.         // 此事件就会自动重置。  
    29.   
    30.         _newItemEvent = new AutoResetEvent(false);  
    31.   
    32.   
    33.         // ManualResetEvent 用于“退出”事件,因为  
    34.   
    35.         // 我们希望发出此事件的信号时有多个线程响应。  
    36.   
    37.         // 如果使用 AutoResetEvent,事件  
    38.   
    39.         // 对象将在单个线程作出响应之后恢复为   
    40.   
    41.         // 未发信号的状态,而其他线程将  
    42.   
    43.         // 无法终止。  
    44.   
    45.         _exitThreadEvent = new ManualResetEvent(false);  
    46.   
    47.   
    48.         // 这两个事件也放在一个 WaitHandle 数组中,以便  
    49.   
    50.         // 使用者线程可以使用 WaitAny 方法  
    51.   
    52.         // 阻塞这两个事件。  
    53.   
    54.         _eventArray = new WaitHandle[2];  
    55.   
    56.         _eventArray[0] = _newItemEvent;  
    57.   
    58.         _eventArray[1] = _exitThreadEvent;  
    59.   
    60.     }  
    61.   
    62.   
    63.     // 公共属性允许对事件进行安全访问。  
    64.   
    65.     public EventWaitHandle ExitThreadEvent  
    66.   
    67.     {  
    68.   
    69.         get { return _exitThreadEvent; }  
    70.   
    71.     }  
    72.   
    73.     public EventWaitHandle NewItemEvent  
    74.   
    75.     {  
    76.   
    77.         get { return _newItemEvent; }  
    78.   
    79.     }  
    80.   
    81.     public WaitHandle[] EventArray  
    82.   
    83.     {  
    84.   
    85.         get { return _eventArray; }  
    86.   
    87.     }  
    88.   
    89.   
    90.     private EventWaitHandle _newItemEvent;  
    91.   
    92.     private EventWaitHandle _exitThreadEvent;  
    93.   
    94.     private WaitHandle[] _eventArray;  
    95.   
    96. }  
    97.   
    98.   
    99. // Producer 类(使用一个辅助线程)  
    100.   
    101. // 将项异步添加到队列中,共添加 20 个项。  
    102.   
    103. public class Producer   
    104.   
    105. {  
    106.   
    107.     public Producer(Queue<int> q, SyncEvents e)  
    108.   
    109.     {  
    110.   
    111.         _queue = q;  
    112.   
    113.         _syncEvents = e;  
    114.   
    115.     }  
    116.   
    117.     public void ThreadRun()  
    118.   
    119.     {  
    120.   
    121.         int count = 0;  
    122.   
    123.         Random r = new Random();  
    124.   
    125.         while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))  
    126.   
    127.         {  
    128.   
    129.             lock (((ICollection)_queue).SyncRoot)  
    130.   
    131.             {  
    132.   
    133.                 while (_queue.Count < 20)  
    134.   
    135.                 {  
    136.   
    137.                     _queue.Enqueue(r.Next(0, 100));  
    138.   
    139.                     _syncEvents.NewItemEvent.Set();  
    140.   
    141.                     count++;  
    142.   
    143.                 }  
    144.   
    145.             }  
    146.   
    147.         }  
    148.   
    149.         Console.WriteLine("Producer thread: produced {0} items", count);  
    150.   
    151.     }  
    152.   
    153.     private Queue<int> _queue;  
    154.   
    155.     private SyncEvents _syncEvents;  
    156.   
    157. }  
    158.   
    159.   
    160. // Consumer 类通过自己的辅助线程使用队列  
    161.   
    162. // 中的项。Producer 类使用 NewItemEvent   
    163.   
    164. // 将新项通知 Consumer 类。  
    165.   
    166. public class Consumer  
    167.   
    168. {  
    169.   
    170.     public Consumer(Queue<int> q, SyncEvents e)  
    171.   
    172.     {  
    173.   
    174.         _queue = q;  
    175.   
    176.         _syncEvents = e;  
    177.   
    178.     }  
    179.   
    180.     public void ThreadRun()  
    181.   
    182.     {  
    183.   
    184.         int count = 0;  
    185.   
    186.         while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)  
    187.   
    188.         {  
    189.   
    190.             lock (((ICollection)_queue).SyncRoot)  
    191.   
    192.             {  
    193.   
    194.                 int item = _queue.Dequeue();  
    195.   
    196.             }  
    197.   
    198.             count++;  
    199.   
    200.         }  
    201.   
    202.         Console.WriteLine("Consumer Thread: consumed {0} items", count);  
    203.   
    204.     }  
    205.   
    206.     private Queue<int> _queue;  
    207.   
    208.     private SyncEvents _syncEvents;  
    209.   
    210. }  
    211.   
    212.   
    213. public class ThreadSyncSample  
    214.   
    215. {  
    216.   
    217.     private static void ShowQueueContents(Queue<int> q)  
    218.   
    219.     {  
    220.   
    221.         // 对集合进行枚举本来就不是线程安全的,  
    222.   
    223.         // 因此在整个枚举过程中锁定集合以防止  
    224.   
    225.         // 使用者和制造者线程修改内容  
    226.   
    227.         // 是绝对必要的。(此方法仅由  
    228.   
    229.         // 主线程调用。)  
    230.   
    231.         lock (((ICollection)q).SyncRoot)  
    232.   
    233.         {  
    234.   
    235.             foreach (int i in q)  
    236.   
    237.             {  
    238.   
    239.                 Console.Write("{0} ", i);  
    240.   
    241.             }  
    242.   
    243.         }  
    244.   
    245.         Console.WriteLine();  
    246.   
    247.     }  
    248.   
    249.   
    250.     static void Main()  
    251.   
    252.     {  
    253.   
    254.         // 配置结构,该结构包含线程同步  
    255.   
    256.         // 所需的事件信息。  
    257.   
    258.         SyncEvents syncEvents = new SyncEvents();  
    259.   
    260.   
    261.         // 泛型队列集合用于存储要制造和使用的  
    262.   
    263.         // 项。此例中使用的是“int”。  
    264.   
    265.         Queue<int> queue = new Queue<int>();  
    266.   
    267.   
    268.         // 创建对象,一个用于制造项,一个用于  
    269.   
    270.         // 使用项。将队列和线程同步事件传递给  
    271.   
    272.         // 这两个对象。  
    273.   
    274.         Console.WriteLine("Configuring worker threads...");  
    275.   
    276.         Producer producer = new Producer(queue, syncEvents);  
    277.   
    278.         Consumer consumer = new Consumer(queue, syncEvents);  
    279.   
    280.   
    281.         // 为制造者对象和使用者对象创建线程  
    282.   
    283.         // 对象。此步骤并不创建或启动  
    284.   
    285.         // 实际线程。  
    286.   
    287.         Thread producerThread = new Thread(producer.ThreadRun);  
    288.   
    289.         Thread consumerThread = new Thread(consumer.ThreadRun);  
    290.   
    291.   
    292.         // 创建和启动两个线程。  
    293.   
    294.         Console.WriteLine("Launching producer and consumer threads...");          
    295.   
    296.         producerThread.Start();  
    297.   
    298.         consumerThread.Start();  
    299.   
    300.   
    301.         // 为制造者线程和使用者线程设置 10 秒的运行时间。  
    302.   
    303.         // 使用主线程(执行此方法的线程)  
    304.   
    305.         // 每隔 2.5 秒显示一次队列内容。  
    306.   
    307.         for (int i = 0; i < 4; i++)  
    308.   
    309.         {  
    310.   
    311.             Thread.Sleep(2500);  
    312.   
    313.             ShowQueueContents(queue);  
    314.   
    315.         }  
    316.   
    317.   
    318.         // 向使用者线程和制造者线程发出终止信号。  
    319.   
    320.         // 这两个线程都会响应,由于 ExitThreadEvent 是  
    321.   
    322.         // 手动重置的事件,因此除非显式重置,否则将保持“设置”。  
    323.   
    324.         Console.WriteLine("Signaling threads to terminate...");  
    325.   
    326.         syncEvents.ExitThreadEvent.Set();  
    327.   
    328.   
    329.         // 使用 Join 阻塞主线程,首先阻塞到制造者线程  
    330.   
    331.         // 终止,然后阻塞到使用者线程终止。  
    332.   
    333.         Console.WriteLine("main thread waiting for threads to finish...");  
    334.   
    335.         producerThread.Join();  
    336.   
    337.         consumerThread.Join();  
    338.   
    339.     }  
    340.   
    341. }  
    1. namespace WindowsFormsApplication1  
    2. {  
    3.     public partial class Form3 : Form  
    4.     {  
    5.         public Form3()  
    6.         {  
    7.             InitializeComponent();  
    8.         }  
    9.         public delegate void Delegate1();  
    10.         public delegate void Delegate2(DataTable dt);  
    11.         public void buttonFind_Click(object sender, EventArgs e)  
    12.         {  
    13.             Delegate1 d1 = new Delegate1(Find);  
    14.             d1.BeginInvoke(new AsyncCallback(AsyncCallback1), d1);  
    15.         }  
    16.         public void AsyncCallback1(IAsyncResult iAsyncResult)  
    17.         {  
    18.             Delegate1 d1 = (Delegate1)iAsyncResult.AsyncState;  
    19.             d1.EndInvoke(iAsyncResult);  
    20.         }  
    21.         public void Find()  
    22.         {  
    23.             DataTable dt = new DataTable();  
    24.             dt.Columns.Add("name", typeof(string));  
    25.             dt.Columns.Add("age", typeof(int));  
    26.             AddRow(dt, "张三", 19);  
    27.             AddRow(dt, "张三", 19);  
    28.             AddRow(dt, "李四", 18);  
    29.             this.Invoke(new Delegate2(Bind2), new object[] { dt });  
    30.         }  
    31.         public void AddRow(DataTable dt, string nameint age)  
    32.         {  
    33.             DataRow dr = dt.NewRow();  
    34.             dr["name"] = name;  
    35.             dr["age"] = age;  
    36.             dt.Rows.Add(dr);  
    37.         }  
    38.         public void Bind2(DataTable dt)  
    39.         {  
    40.             this.dataGridView1.DataSource = dt;  
    41.         }  
    42.     }  
    43. }  
  • 相关阅读:
    jsp 特殊标签
    poj 1753 Flip Game 高斯消元 异或方程组 求最值
    zoj 3155 Street Lamp 高斯消元 异或方程组 求方案数
    poj1222 EXTENDED LIGHTS OUT 高斯消元解异或方程组 模板
    zoj 3930 Dice Notation 模拟
    zoj 3157 Weapon 线段树求逆序对数
    hdu 1242 Rescue BFS+优先队列
    hdu 3466 Proud Merchants 贪心+01背包
    zoj 3689 Digging 贪心+01背包
    hdu 2602 Bone Collector 01背包模板
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/3110500.html
Copyright © 2011-2022 走看看