线程同步
  synchronized(this)和synchronized(MyClass.class)区别:前者与加synchronized的成员方法互斥,后者和加synchronized的静态方法互斥
  synchronized的一个应用场景是单例模式的,双重检查锁

 

public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}

 

  注意:不过双重检查锁返回的实例可能是没有构造完全的对象,高并发的时候直接使用有问题,不知道在新版的java里是否解决了
  所以有了内部类方式的单例模式,这样的单例模式有了延迟加载的功能(还有一种枚举方式的单例模式,用的不多,有兴趣的可以上网查)

//(推荐)延迟加载的单例模式
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
  若不要延迟加载,在类加载的时候实例化对象,那直接这么写,如下:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}

  volatile保证同一变量在多线程中的可见性,所以它更多是用于修饰作为开关状态的变量
  用synchronized修饰变量的get和set方法,不但可以保证和volatile修饰变量一样的效果(获取新值),因为synchronized不仅会把当前线程修改的变量的本地副本同步给主存,还会从主存中读取数据更新本地副本。而且synchronized还有互斥的效果,可以有效控制并发修改一个值,因为synchronized保证代码块的串行执行。如果只要求获取新值的特性,用volatile好,因为volatile比较轻量,性能较好。