synchronized
什么是synchronized
为什么使用synchronized
synchronized的用法
1.同步非静态方法(实例方法)
public class synchronizedTest implements Runnable { static int i =0; public synchronized void increase(){ i++; } @Override public void run(){ for (int j =0 ; j<10000;j++){ increase(); } } public static void main(String[] args) throws InterruptedException { synchronizedTest test = new synchronizedTest(); Thread t1 = new Thread(test); Thread t2 = new Thread(test); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); } }
2.同步静态方法
public class synchronizedTest implements Runnable { static int i =0; public static synchronized void increase(){ i++; } @Override public void run(){ for (int j =0 ; j<10000;j++){ increase(); } } public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new synchronizedTest()); Thread t2 = new Thread(new synchronizedTest()); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); }
3.同步代码块
public class synchronizedTest implements Runnable { static synchronizedTest instance=new synchronizedTest(); static int i=0; @Override public void run() { //使用同步代码块对变量i进行同步操作,锁对象为instance synchronized(instance){ for(int j=0;j<10000;j++){ i++; } } } public static void main(String[] args) throws InterruptedException { Thread t1=new Thread(instance); Thread t2=new Thread(instance); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); } }
JVM对synchronized的优化
自旋锁:线程频繁的从阻塞到唤醒这段时间,可能会非常耗时,那么自旋锁就会让线程等待一段时间,执行一段无意义的代码(通常是无意义的循环)
锁消除:指有的时候为了保证数据的完整性,我们通常要对这部分代码执行同步控制,但是在某些情况下jvm检测到不存在竞争条件,jvm会将这段同步代码中消除锁
锁粗化:有些时候需要让同步代码的作用范围要尽可能小点,但是有些情况我们需要对多个小部位的加锁替换成整体加锁
轻量级锁:引入轻量级锁的主要目的是在多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。当关闭偏向锁功能或者多个线程竞争偏向锁导致偏向锁升级为轻量级锁,则会尝试获取轻量级锁
偏向锁:为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径。上面提到了轻量级锁的加锁解锁操作是需要依赖多次CAS原子指令的
重量级锁:指没有优化过的同步方法或者同步代码块
Java锁使用的锁其实是在对象头的中锁标识,下面是锁在对象头中的结构
锁的状态