首页 > 代码库 > 整理:java定时器。

整理:java定时器。

本文纯属个人思路,如有错误,请指正。

 

java的Timer依赖Thread,每一个Timer实际上都是一个Thread。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.TimerTask;
 
/**
 * 本类仅为实现TimerTask,意义不大。
 * @author 9082046**@qq.com
 *
 */
public class Task  extends TimerTask
{  
    public void run()
    {
        System.out.println(this.hashCode());       
    }
}

 

  在win7 的myeclipse8.5的默认安装后的未做任何调节的开发环境下:

方案一:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Timer;
 
/**<br> * 启动1w个Timer
 * @author 9082046**@qq.com
 *
 */
public class TestTimer
{  
    public static void main(String[] args)
    {
        add(10000);
    }
    public static void add(int amount)
    {      
        for(int index=0;index < amount; index ++)
        {          
            Timer timer=new Timer();
            timer.schedule(new Task(), Integer.MAX_VALUE);
        }
    }
}

启动1w个的Timer,结果如下:

才1w个Timer提示jvm的内存不够使的了。

 

方案二:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 *
 */
package linked_array;
 
import java.util.Random;
import java.util.Timer;
 
/**
 * @author 908204694@qq.com
 *
 */
public class TestTimer
{  
    public static void main(String[] args)
    {
        add(10000);
    }
    public static void add(int amount)
    {      
        Timer timer=new Timer();
        for(int index=0;index < amount; index ++)
        {          
            timer.schedule(new Task(), Integer.MAX_VALUE);
        }
    }
}

 同一个Timer调度1w个TimerTask,至少在运行5分钟后没出什么Error。。。。貌似有点囧,也没任何输出,写的Timer调度TimerTask的延迟时间有点大,哈。

 在实际应用中,Timer存在计时器线程终止 或者 计时器取消 导致的 IllegalStateException,单个Timer 或许不太适合长时间 调度 非重复事件 TimerTask。

原因:对 Timer 对象最后的引用完成后,并且 所有未处理的任务都已执行完成后,计时器的任务执行线程会正常终止(并且成为垃圾回收的对象)。但是这可能要很长时间后才发生。出自:jdk api 1.6.0 java.util  类 Timer。

 

方案三:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
 * @author 9082046**@qq.com
 *
 */
public class User
{
    private int user_id;
    // 用来标识时间
    private int time_stamp;
    public User(int userId, int timeStamp)
    {
        user_id = userId;      
        time_stamp = timeStamp;
    }
     
    public int getUser_id()
    {
        return user_id;
    }
         
    public int getTime_stamp()
    {
        return time_stamp;
    }
 
    public void setTime_stamp(int timeStamp)
    {
        time_stamp = timeStamp;
    }  
}
 
 
/**
 * @author 9082046**@qq.com
 *
 */
public class Test_Timer
{
 
    private static ArrayList<User> list=new ArrayList<User>(); 
    private static Random randam=new Random();
     
    // 计时用,每秒加一。或者直接用时间戳吧。
    private static int timeS = 0;  
    private static final int tenS = 10;
     
    public static void main(String[] args)
    {
        add(10000);
         
        while(true)
        {
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                 
            }          
            traveral();
            timeS++;
        }      
    }
 
        public static void add(int amount)
        {
            for(int index=0;index < amount; index ++)
            {
                int random = randam.nextInt(1000);
                User user =new User(index,random);         
                list.add(user );
            }
        }
         
        /**
         * 遍历全部的玩家。
         */
        public static void traveral()
        {
            int amount=list.size();
            User user = null;
            for(int index=0;index < amount; index ++)
            {      
                user = list.get(index);
                if(user.getTime_stamp() < timeS)
                {
                    System.out.println("userId:"+user.getUser_id() +"," +user.getTime_stamp());
                    user.setTime_stamp(user.getTime_stamp()+tenS);
                }
            }
        }
}

 

使用Thread.sleep() + 遍历全部数据实体并比较时间标记位   :模拟计时器。

 

 

 

个人注:

①、 主动让系统回收垃圾对象:System.gc()。

②、方案二 和 方案三 都存在缺陷, 如果存在长耗时的任务,会导致后续的部分任务 晚于预设的时间标识点才能执行。