毛毛的小窝 — 关注技术交流、让我们一起成长

导航

(原) “线程池”的一个小例子

/*
 * “线程池”是可以用来在后台执行多个任务的线程集合。
 * 线程池通常具有最大线程数限制。如果所有线程都繁忙,则额外的任务将放入队列中,直到有线程可用时才能够得到处理。
 * ThreadPool.QueueUserWorkItem: 将用户方法排入队列以便执行。此方法在有线程池线程变得可用时执行。
 * ManualResetEven: 通知一个或多个正在等待的线程已发生事件。_doneEvent.Set() 将事件状态设置为终止状态
 * 当计算完成时,每个对象都通知提供的事件对象,使主线程用 WaitAll 阻止执行,直到十个 Fibonacci 对象全部计算出了结果。
 * EventWaitHandle表示一个线程同步事件。WaitHandle封装等待对共享资源的独占访问的操作系统特定的对象。
 * ManualResetEven 继承于 EventWaitHandle,EventWaitHandle 继承于 WaitHandle
 * 考虑1:如何获取哪个任务已经完成? if _doneEvent.Set(); then event end.
 * 考虑2:如何获取事件的状态。ManualResetEvent 哪个属性使我们了解这个事件已经结束?请高手回答。
*/


namespace FibonacciPool11
{
    
using System;
    
using System.Threading;


    
// Fibonacci
    public class Fibonacci
    
{
        
private int _n;
        
private int _fibOfN;
        
private ManualResetEvent _doneEvent;
        
        
public Fibonacci(int n,ManualResetEvent doneEvent)
        
{
            _n 
= n;
            _doneEvent 
= doneEvent;
        }


        
// Wrapper method for use with thread pool.
        public void ThreadPoolCallback(Object threadContext)
        
{
            
int threadIndex = (int)threadContext;
            Console.WriteLine(
"thread {0} started", threadIndex);
            _fibOfN 
= Calculate(_n);
            Console.WriteLine(
"thead {0} result calculated", threadIndex);
            _doneEvent.Set();  
// 将事件状态设置为终止状态,允许一个或多个等待线程继续
            Console.WriteLine("thead {0} ,Fibonacci ({1}) = {2}", threadIndex,_n, _fibOfN); // 事件终止后显示结果
        }


        
// Recursive method that calculates the Nth Fibonacci number.
        public int Calculate(int n)
        
{
            
if (n <= 1)
                
return n;
            
return Calculate(n - 1+ Calculate(n - 2);
        }


        
// Properties
        public int N get return _n; } }

        
public int FibOfN get return _fibOfN; } }

        
    }



    
class Program
    
{
        
static void Main(string[] args)
        
{
            
const int FibonacciCalculations = 10;

            
// One event is used for each Fibonacci object
            ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
            Fibonacci[] fibArray 
= new Fibonacci[FibonacciCalculations];
            Random r 
= new Random();

            
// Configure and launch threads using ThreadPool
            Console.WriteLine("launching {0} tasks", FibonacciCalculations);
            
for (int i = 0; i < FibonacciCalculations; i++)
            
{
                doneEvents[i] 
= new ManualResetEvent(false);
                Fibonacci f 
= new Fibonacci(r.Next(1030),doneEvents[i]);
                fibArray[i] 
= f;
                ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i); 
// 任务入队
            }

            
            
// Wait for all theads in pool to calculation
            WaitHandle.WaitAll(doneEvents);  // 等待所有的元素都收到信号
            Console.WriteLine("All calculations are complete.");

            
// Disply the results
            for (int i = 0; i < FibonacciCalculations; i++)
            
{
                Fibonacci f 
= fibArray[i];
                Console.WriteLine(
"Fibonacci ({0}) = {1}", f.N, f.FibOfN);
            }

            

            
// waiting
            Console.ReadLine();
        }

    }

}

posted on 2007-12-31 13:26  mjgforever  阅读(539)  评论(0编辑  收藏  举报