zoukankan      html  css  js  c++  java
  • 别拿Thread当定时器使用...

    经常可以看到很多程序使用Thread当作定时器(Timer)使用,例如定时检查数据,定时清空缓存什么的

    就像以下代码

    代码
    Thread t = new Thread(p =>
    {
    while (true)
    {
    //做点什么...例如刷新数据 操作缓存 和其他定时任务
    Thread.Sleep(10000);
    }
    });
    t.Start();

    可能有的朋友已经注意到,在压力比较大的Asp.net网站中这个Thread经常不能正常的工作,也许这个线程会永远不会再起来.......那么定时任务也就泡汤了

    PS:如果是console的主线程 (标记了STAThreadAttribute ) 则可以正常的苏醒和睡眠

     另外一个原因就是每个Thread都是很昂贵的,能不用就不用,(我的另外一个文章有提到,一个线程至少1m内存还要考虑给GC 和上下文调度造成的压力)

    一般情况下建议使用System.Threading.Timer 来执行定时任务

      1)System.Threading.Timer由核心模式(Kernel-Mode)触发,不会发生任务跑着跑着没掉的惨案

      2)记得将Timer变量放在类的实例成员或者静态成员上,以免Release模式下Timer被GC了(我的另外一个文章有提到这个情况)

      3)Timer设置定时执行以后,假设到了第二次的执行时间,即使第一次还没有执行完,那么第二次也会开始,可以考虑使用以下两种方案防止多次执行的冲突

        a.Timer设置为只执行一次 ,在Timer调用方法的最后一句,重置一下Timer.Change(int dueTime,int period);

        b.使用一个变量表示当前是否有定时器正在执行,建议用InterLocked操作一个int变量来表示

    PS:不是很推荐使用

      1) System.Timers.Timer 其实是对 System.Threading.Timer的封装

      2) System.Windows.Forms.Timer ,基于消息机制

      3) 特别注意 不要从线程池中拿一个线程来做长期任务,特别是Sleep它

    PS:windows大约30ms才考虑一次线程切换....而且windows一般都有几百个线程- -#

  • 相关阅读:
    java之redis篇(spring-data-redis整合) (转)
    web.xml
    点击类名方法名如何连接到相应的Android源代码
    eclipse能够自动提示变量名.
    Android自定义ActionBar
    Android 自定义View
    android 自定义titlebar
    Android SharedPreferences登录记住密码
    Android 正则表达式验证手机和邮箱格式是否正确
    Android 首次进入应用时加载引导界面
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/1893604.html
Copyright © 2011-2022 走看看