synchronized
被他润饰的办法或代码块在任一时刻只有一个线程执行。
应用 synchronized
-
润饰实例办法 = 对实例加锁,执行前须要取得实例的锁
synchronized void method() {// 业务代码}
-
润饰静态方法 = 对类加锁
synchronized static void method() {// 业务代码}
-
润饰代码块 = 给指定对象 / 类加锁
synchronized(this) {// 业务代码} synchronized(类.class){//blabla}
双重校验锁实现单例模式 线程平安
public class Singleton{ private volatile static Singleton uniqueInstance; private Singleton(){} public static Singleton getInstance(){ // 先判断对象是否曾经实例过 if (uniqueInstance == null){synchronized (Singleton.class){if (uniqueInstance == null){uniqueInstance = new Singleton(); } } } } }
下面代码为什么要用 volatile
uniqueInstance = new Singleton(); 的步骤
1. 给 uni 调配内存地址
2. 初始化 uni
3. 把 uni 指向方才调配的内存地址
因为 jvm 指令重排,上述步骤可能依照 1 3 2 的程序执行,多线程环境下,执行完 3 就有调用方 get 到了 uni,然而此时 uni 还没有被初始化。
volatile 能够防止指令重排。
构造方法自身就是线程平安的
不须要用 synchronized 润饰。