Java时区bug,TimeZone.setDefault()只在当前线程有效
项目是基于GMT时间的,在系统启动的时候,我们就会调用TimeZone.setDefault(timeZone)将默认时区设为GMT。
后来突然发现,有时用户选择的时间经过后台一圈后回产生8个小时误差。又是间歇性的,要他重现的时候又偏不来。苦心debug,终于发现在部分线程中,时区还是GMT+8,后台某个调用可能把时区变为了GMT,8小时误差就产生了。网上一搜,原来是bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6352812
只在部分电脑上有问题,幸好production上是好的,写了一个程序来测试:
import java.util.Date;
import java.util.TimeZone;
public class Test {
@SuppressWarnings("unused")
public static void main(String[] args) throws InterruptedException {
DateThread thread = new DateThread();
thread.start();
TimeZone gmt = TimeZone.getTimeZone("GMT");
Date now = new Date();
System.out.println("main thread,before set timezone:" + now.toString());
TimeZone.setDefault(gmt);
Thread.currentThread().sleep(2000);
thread.resume();
System.out.println("main thread,after set timezone:" + now.toString());
}
}
class DateThread extends Thread {
@SuppressWarnings( { "unused", "deprecation" })
public void run() {
Date now = new Date();
System.out.println("sub thread,before set timezone:" + now.toString());
this.suspend();
System.out.println("sub thread,after set timezone:" + now.toString());
}
}
如果子线程输出的时区一样,就说明有bug
相关文档:
3.1 跨平台三维图形开发工具包Java 3D
官方主页:https://java3d.dev.java.net/
Java 3D严格遵循“建模-绘制”泛型。场景图(scene graph)的 抽象模型被用来组织和维护虚拟场景中的可是对象及其行为。场景图包含了虚拟图形世界的全部信息,Java 3D绘 制引擎会对场景图进行自动绘制。
Java 3D is a scene g ......
1、commons-math/commons-lang-math
以上两个包是apache下的,前者比后者的功能强大,后者有的功能前都有,后者主要解决平时程序中的一些基本的数学计算,主要是范围判断(*Range),随机数生成(JVMRandom,RandomUtils),分数处理(Fraction),数字转化、大小判断(NumberUtils)等。前者可以处理更复杂的数据分 ......
1.1 J2SE
的主要工具
基本工具:
javac
Java
编程语言的编译器。本书各章的程序都是在
DOS
窗口中通过执行
"javac
文件名
”
来编译
Java
程序的。文件名必须以
.java
为后缀,编译以后生成
.class
为后缀的字节码文件。
java
用于执行
Java
应用程序。本书各章的程 ......
网站列表如下:
IBM中国的开发者网站:http://www.ibm.com/developerworks/cn/
IBM中国for java的开发者网站:http://www.ibm.com/developerworks/cn/java/ 中文
IBM中国for java的开发者网站:http://www.ibm.com/developerworks/java 英文
Google代码目录网站:http://c ......
Java编写一个函数交换两个变量的值
Java函数在传递过程中只能够传值,不能传址。这样,函数的参数在函数内部做任何变化就都不会反映到外部调用者来。所以解决之道就是要找到要交换对象的引用。对于普通的值类型,像int或者double这样的可以改传他们的包装类Integer和Double。而对于本来就是引用类型的对象,则需要对他们再 ......