/**
* 1.单列模式与多线程的使用,如果不加synchronized方法锁定对象,
* 就可能会先后创建多个对象,导致之前对象被之后对象覆盖。
*
* 2.下面是不加同步锁的多线程与单列模式。
* public static InstanceOnly getInstance(int flag)里面的代码块没有被锁定,
* 如果锁定加入synchronized(类名.claass)即可。
*
* 3.注解:类名.class 即调用虚拟机中类的对象模板,锁住模板也是一样的。
* 因为JVM创建对象都是根据这个模板来的。
*
* @author 孙乐
*
*/
public class SynSingletion {
public static void main(String[] args){
ThreadInstance ti=new ThreadInstance(); //使用时创建单列模式
Thread t1=new Thread(ti);
Thread t2=new Thread(ti);
t1.start(); //使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
t2.start(); //虚拟机内部是怎么实现自动调用run()方法的,我们不用管。
try {
Thread.sleep(5000); //放大错误,时间越大捕获错误准确率越高,防止CPU没有执行完其它线程
System.out.println("如果出现数字是2证明我已经被第一个线程创建的对象覆盖:"+InstanceOnly.getFlag());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//由于是多线程,线程并行运行,所以可能会创建多个对象,
//后来创建的对象会覆盖之前的对象,达不到单列模式效果
class ThreadInstance implements Runnable{
private int i=0;
public void run(){
i++;
InstanceOnly.getInstance(i); //创建单列对象
}
}
/*类名.class详解:
* 实际上java的每个类被编译成.class文件的时候,java虚拟机(叫jvm)会自动为这
个类生成一个类对象,这个对象保存了这个类的所有信息(成员变量,方法,构造器等),
以后这个类要想实例化(也就是创建类的实例或创建类的对象)那么都要以这个class对
象为蓝图(或模版)来创建这个类的实例。*/
//下面是单列模板,没有使用线程同步锁定
class InstanceOnly {
private static int flag=0; //标记,记录是不是创建了2个对象
private static InstanceOnly instance;
private InstanceOnly(){ //私有化构造函数,不被外界初始化
}
public static InstanceOnly getInstance(int flag){
// synchronized(InstanceOnly.class){ //类名.class为对象的模板
if(null==instance){
InstanceOnly.setFlag(flag);
System.out.println("创建:"+(instance=new InstanceOnly()).toString());
}
// }
return instance;
}
public static int getFlag() {
return flag;
}
public static void setFlag(int flag) {
InstanceOnly.flag = flag;
}
}
--------------------------------------------以上是JAVA多线程创建单列模式与同步的演示代码,
---------------------------------------------目的:提供最大直观性参考。加强逻辑思维。