好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

自制线程池3续

自制线程池3续

晚上睡觉前想到一些问题,发现有几种情形没有进行测试,遂记录下来进行了今天进行了测试

1.在给线程池派发任务执行完成后,间隔一段时间,再给线程池添加任务看是否正常,根据间隔的时间的长短这里可以分为两种情形,一是复用空闲的线程,另一种是创建线程。

创建线程的情况又分为两种,一种是由于间隔时间过长,系统自动将线程结束了,另一种是线程池设定了最大执行任务时间,虽然间隔的时间不长,但是任务的线程是强制销毁的还是要创建新线程来执行下面的任务。

在测试的时间我发我现一个鬼异的现象,我先把我的测试代码例出来

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Threading;
using  ThreadPool2;

namespace  ThreadPoolTest.MyThreadPool2Test
{
     class  Class3
     {
         static   void  Main( string [] args)
         {
            MyThreadPool2 pool = new  MyThreadPool2( 1 , true , 10 * 1000 );
             object  state = new   object ();
            pool.QueueUserWorkItem(call1,state,succ,err);
            Thread.Sleep( 80 * 1000 );
            pool.QueueUserWorkItem(call1, state, succ, err);
            Thread.Sleep( 50 *   1000 );
            pool.QueueUserWorkItem(call1, state, succ, err);

            Console.ReadLine();
        }

         private   static   void  err( object  state)
         {
            Console.WriteLine( " err " );
        }

         private   static   void  succ( object  state,  object  result)
         {
            Console.WriteLine( " succ " );
        }

         private   static   object  call1( object  state)
         {
             while ( true )
             {
                Console.WriteLine( " call1 " );
                Thread.Sleep( 2000 );
            }
        }
    }
}

这里正常的情况应该是这样,执行单项任务最长为10s,两次向线程池提交任务都会创建新的线程来执行,因为10s,第一项加入线程池的任务是完不成的需要强行销毁线程。所以第二项不能复用第一项的任务。

这里有趣的现象是,我发现第一项任务的执行时间将近20s,而后面第二次加入的任务执行都是标准的10s这个是为什么?

明明设定了最大执行10s,仅是第一次执行任务不是,为什么?

最后我发现的原因是这样,由于实例化线程池时就开始轮询检测是否有超时任务,而此时还没有向线程池中添加任务,当向线程池中添加任务后,轮询到达第一次10s检测时间,而此时任务的执行时间还未到10s,等到第二次轮询到达时才认为任务超时了,所以第一次加入的任务它比后面的任务执行的长间较长,我们可以通过下面的代码来显现我的观点的正确性

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Threading;
using  ThreadPool2;

namespace  ThreadPoolTest.MyThreadPool2Test
{
     class  Class3
     {
         static   void  Main( string [] args)
         {
            MyThreadPool2 pool = new  MyThreadPool2( 1 , true , 10 * 1000 );
             Thread.Sleep( 5000 );
             object  state = new   object ();
            pool.QueueUserWorkItem(call1,state,succ,err);
            Thread.Sleep( 80 * 1000 );
            pool.QueueUserWorkItem(call1, state, succ, err);
            Thread.Sleep( 50 *   1000 );
            pool.QueueUserWorkItem(call1, state, succ, err);

            Console.ReadLine();
        }

         private   static   void  err( object  state)
         {
            Console.WriteLine( " err " );
        }

         private   static   void  succ( object  state,  object  result)
         {
            Console.WriteLine( " succ " );
        }

         private   static   object  call1( object  state)
         {
             while ( true )
             {
                Console.WriteLine( " call1 " );
                Thread.Sleep( 2000 );
            }
        }
    }
}

上图是原来的结果

下图是加了Thread.Sleep(5000)的结果,可以看出,执行的时间少了5s钟,由此可以证明确实是因为记时和任务执行的时间不一致性所引起的。

我本来想改进一下,可后来想了想还是算了,这个问题不大,因为在实际项目中,我们只是要将死亡的任务销毁,我们不需要太过精确,只能执行10分钟,一分也不能多或不能少,差不多就行。

不过等我静下心来,我可以认真的去改进它

查看更多关于自制线程池3续的详细内容...

  阅读:39次