public class SyncObj { private static SyncObj obj = null; private SyncObj(){ } public static SyncObj getIns(){ if(obj==null){ System.out.println("obj=null"); obj = new SyncObj(); return obj; } return obj; } public synchronized void say(){ System.out.println("hello world.."); } }
================================== 在普通的main方法里测,没什么问题 ================================== public static void main(String[] args) { // TODO Auto-generated method stub SyncObj obj1 = SyncObj.getIns(); SyncObj obj2 = SyncObj.getIns(); obj1.say(); obj2.say(); System.out.println(obj1); System.out.println(obj2); obj1、obj2是同一个object
==================================== 但是在线程里,就不一定是这样了 ====================================
--------------------------------- 1.主线程跟子线程都去获得这个实例 --------------------------------- public class MyThread extends Thread{ @Override public void run() { super.run(); SyncObj obj1 = SyncObj.getIns(); System.out.println(Thread.currentThread().getName()+":"+obj1); obj1.say(); } }
----main方法里: public static void main(String[] args) { SyncObj obj1 = SyncObj.getIns(); System.out.println(Thread.currentThread().getName()+":"+obj1);
Thread th1 = new MyThread(); Thread th2 = new MyThread(); th1.start(); th2.start(); } ----这个里面obj都是同一个 ----因为主线程里先geIns(),就先初始化了SyncObj里的类变量, ----然后在子线程里得到的是同一个obj,所以SyncObj里的sync方法也有意义
------------------------------------ 2.主线程没有获得这个实例,直接开子线程 --也就是说子线程开始前,SyncObj没有没赋值 ------------------------------------ public static void main(String[] args) { Thread th1 = new MyThread(); Thread th2 = new MyThread(); th1.start(); th2.start(); } ----结果是:********得到2个不同的obj******** ----所以这个SyncObj的sync方法也没有意义!!!
==================================================== 改进代码: SyncObj里加上static块: ==================================================== public class SyncObj { static{ if(obj==null){ obj = getIns(); } } 。。。 } ----这样就是得到同一个实例 ----sync的方法才有意义