zoukankan      html  css  js  c++  java
  • 自制线程池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分钟,一分也不能多或不能少,差不多就行。

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

  • 相关阅读:
    expdp定时备份
    设计模式简介
    利用Python制作万年历
    Linux下Python的安装
    排序算法-直接插入排序
    排序算法-冒泡排序
    数据结构-循环顺序队列&链队列
    数据结构-栈&链栈
    数据结构-双向链表&双向循环链表
    数据结构-单链表&单循环链表
  • 原文地址:https://www.cnblogs.com/lexus/p/1266847.html
Copyright © 2011-2022 走看看