最近用java线程写了一个每隔10分钟写日志文件的
程序放在solaris上运行,老是出现问题,又没什么
规律,有时线程连续运行7天就死悄悄了,有时3,4天,
有时个把月才死,死之后又没什么错误,又没内存
泄漏,也可以保证不会存在死锁,用JProfiler也没
发现什么可疑之处,郁闷,害得客户老要重启。
程序放在solaris上运行,老是出现问题,又没什么
规律,有时线程连续运行7天就死悄悄了,有时3,4天,
有时个把月才死,死之后又没什么错误,又没内存
泄漏,也可以保证不会存在死锁,用JProfiler也没
发现什么可疑之处,郁闷,害得客户老要重启。
solaris9(SPARC)中文操作系统
JDK1.4(solaris9自带的)
并且至少能连续运行1个月不出问题的,
好给我个安慰,我在java上花了好大功夫(光是买书都花了2000多RMB),
现在用得越来越不顺手了,希望是我的错,不是JAVA的错。
http://community.csdn.net/Expert/topic/3932/3932563.xml?temp=.9485437
try {
sleep(600000L);
}catch(Exception e) {}
因为该日志线程是独立的,跟其他线程没任何关系,
就是一个死循环,所以并没有捕获异常,或许是因为
线程sleep太久了,偶尔会发生异常,是不是OS或VM
把线程给干掉了?
timer.scheduleAtFixedRate(wApp,beginDate,24*60*60*1000);
这里wApp是你的计划类的,在网上找找很多的..
=============================================
wpx80(wpx80) 大虾能否讲讲其中奥妙!
另外Timer是javax.swing.Timer?还是java.util.Timer?
public void run() {
System.out.println("this is test!!");
}
}import java.util.Timer;public class WeatherApp {
public Timer timer;
public TakeWeather wApp;
public void start(){
timer=new Timer();
wApp=new TakeWeather();
timer.scheduleAtFixedRate(wApp,0,5*1000);
}
public static void main(String[] args) {
try{
WeatherApp app=new WeatherApp();
app.start();
}catch(Exception e){}
}
}
这样,每个5秒钟打印一条数据...
各有什么好处和坏处?
为什么Thead就不能sleep太久呢?难道timer.scheduleAtFixedRate()
将间隔设置10分钟以后就一定不出问题吗?我查了一下API源代码Thead类用到了native,Timer类好像没看到有native?
========================================================
我只想确认将线程Sleep这么长时间是否存在问题,
solaris下也有crontab,但并不是最终目的,
因为我所举的只是一个最简单的例子,真实系统中的功能用计划任务实现并不理想。我看JDK里的API说明,它并没说有时间限制。
确实是真的动了功夫!^_^我感觉这个情况用java.util.Timer类来定时运行TimerTask 是个好的办法!
至于楼主想探个究竟为什么Thread出问题,是否jvm在客户那里有可能被停止过!
======================================================================
可以确定jvm没停过,因为其他线程并没有死,
今天重新改了一下系统
将
try {
sleep(600000L);
}catch(Exception e) {}
改成
try {
sleep(600000L);
}catch(Exception e) {System.out.println(e);}
重新确认一下到低是否是sleep引出的问题,
并开了一个监控线程,每格20秒钟,打印当前活动线程
========================================================================
因为我所举的只是一个独立线程,不需要wait,notify.我看过人民邮电出版社的<<JAVA线程编程>>
中国电力出版社的<<JAVA线程(第二版)>>以及CoreJava2 II
作者都没提到这些注意事项,sun的JDK文档也没说,真是郁闷...我现在都在想自己到底是不是适合写程序了,
java断断续续学了差不多三年了,用也用了很久了,书也看了N多,什么
java与模式,JVM,安全,J2ee的方方面面,甚至连J2ME都看了,
现在反而用起来越来越不顺心,
跟大家说个我找BUG的笑话,为了找出系统不定期的OutOfMemoryError
我差不多花了一年,
我们的系统中有这样一段程序(简化了)import java.net.Socket;
public class SocketProxy extends Thread {
....
private Socket socket=null; public boolean connect() {
//主要用来连接Socket,初始IO
} public void run() {
connect();
}
}public class Test1 extends Thread {
public static void main(String[] args) {
Test1 test1=new Test1();
test1.start();
}
public void run() {
while(true) {
SocketProxy sp=new SocketProxy();
sp.start();
...
sleep(20000);
....
}
}
}public class Test2 extends Thread {
public static void main(String[] args) {
Test2 test2=new Test2();
test2.start();
}
public void run() {
while(true) {
SocketProxy sp=new SocketProxy();
sp.connect();
...
sleep(20000);
....
}
}
}之前因为从不用Profiler,所以找了大半年都找不到哪里错了,
后来费了好大功夫下了个JProfiler,细细观察在Test2中分配
的SocketProxy sp竟然越new越多,而在Test1中分配
的SocketProxy sp会时不时的会回收一下,
最后把SocketProxy类改成这样
import java.net.Socket;
public class SocketProxy {
....
private Socket socket=null; public boolean connect() {
//主要用来连接Socket,初始IO
}
}
再Profiler一下Test2,分配
的SocketProxy sp也会时不时的会回收一下了,最后得出一个结论:
如果要new一个继承了Thread的类的实例,如果不调用
start(),GC不管事,new再多它也不理,直到OutOfMemoryError。或许是我太蠢了,干吗要这么用,或许哪还有个开关我没设好。
其中Test2类是有问题的,SocketProxy sp的实例会不断增加,GC不会回收
(只可惜CSDN不能贴图);public class SocketProxy extends Thread {
public void connect() {
System.out.println(new java.util.Date());
} public void run() {
connect();
}
}public class Test1 extends Thread {
public static void main(String[] args) {
Test1 test1=new Test1();
test1.start();
}
public void run() {
while(true) {
SocketProxy sp=new SocketProxy();
sp.start();
try
{
sleep(50);
}
catch (Exception e) {}
}
}
}public class Test2 extends Thread {
public static void main(String[] args) {
Test2 test2=new Test2();
test2.start();
}
public void run() {
while(true) {
SocketProxy sp=new SocketProxy();
sp.connect();
try
{
sleep(50);
}
catch (Exception e) {}
}
}
}public class SocketProxy3 {
public void connect() {
System.out.println(new java.util.Date());
}
}public class Test3 extends Thread {
public static void main(String[] args) {
Test3 test3=new Test3();
test3.start();
}
public void run() {
while(true) {
SocketProxy3 sp=new SocketProxy3();
sp.connect();
try
{
sleep(50);
}
catch (Exception e) {}
}
}
}
try {
sleep(600000L);
}catch(Exception e) {}
的问题。 其他代码呢/?比如写日志文件在哪儿呢
一般在构造函数里写start()函数,或者加个旗标判断!
例如:用Thread.sleep(1)计数1秒会少于1000,而用timer.scheduleAtFixedRate()
来计数会刚好1000。
================================
没看thinking in java这本书,找机会看看。谢谢!!
=========================
C++不太熟,有时间再补补,不过还是非常感谢您提的建议!
一般在构造函数里写start()函数,或者加个旗标判断!
===========================
调用线程start()的地方应该没什么问题的,我看一些开源的代码也不一定
就在构造函数里写。