首先synchronized的使用很简单 就是在放在需要同步的代码快中,让后知道什么时候用什么样的锁就行了。但是楼主上面说的那种延迟加载的单例模式很特殊,里面使用了双重判断,所以感觉很晕。
代码如果这样写,这个会先判断s是否等于null,如果为空则进去new 一个Single对象。这样的代码在多线程中是有安全隐患的,因为变量s是共享数据,而且有两句代码都操作了s这个变量。
if(s==null)
{
//如果一个线程运行到这里刚好被切换,另一个线程也进来,同时也满足if判断,如果两个线程都执行完后都会返回一个Single对象,这时也不会保证对象的唯 一了。
s=new Single();
}
return s;
这时需要同步
synchronized(Single.class)//因为getInstance()是静态方法,所以需要用到Single的字节码文件锁
{
if(s==null)
s = new Single();
}
其实想上面这样写,代码已经没有问题了。但是如果每次调用这个方法的话都会去同步和判断锁,是很浪费资源的。所以在外面再判断一次。如果s不为空了后,直接返回,就不会进入到同步代码块中,所以第一个判断完全是为了代码执行效率。
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s = new Single();
}
} |