本文纯属个人思路,如有错误,请指正。
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()。
②、方案二 和 方案三 都存在缺陷, 如果存在长耗时的任务,会导致后续的部分任务 晚于预设的时间标识点才能执行。