JDK1.6之后关于synchronized的优化

JDK1.6之后关于synchronized优化:
CAS(compare and swap)
CAS(O,V,N) O:当前线程认为主内存的值 V:主内存中的实际值 N:希望更新的值
执行CAS的线程,只有首次获得CPU时间片段的线程才能修改主内存的值

例如: 有20张票,int ticket = 20;
有三个线程在卖票
线程 - 1 Ticket-1 = 20
ticket-1 = 19
线程 – 2 Ticket-2 = 20
线程 – 3 Ticket-3 = 20

CPU----线程-3执行 – 5 Ticket-3 = 15
此时执行CAS(O,V,N) ---- CAS(20,20,15)
此时 O == V 可以将 V修改为N
CPU----线程-1 执行 –1
此时执行CAS CAS(20,15,19)
此时 O != V 不能修改主内存值
需要将O改为15 进行下一下循环

自旋:处理器上跑无用指令,但是线程不阻塞
自适应自旋:(重量级锁的优化)
JVM给一个时间段,在该时间段内,线程是自旋状态,若在该时间段内获取到锁,下一次适当延长自旋时间;否则将线程阻塞,下一次适当缩短自旋时间。

随着锁竞争的激烈程度不断升级,没有降级过程。
偏向 -> 轻量级锁 -> 重量级锁(自适应自旋)(jdk1.6之前synchronized默认实现)—线程获取锁失败进入阻塞态(OS用户态->内核态)

JDK1.6 默认先偏向锁(首先就是偏向锁)

偏向锁(乐观锁,锁一直是一个线程在来回的获取):
当线程第一次获取锁时,将偏向锁线程置为当前线程,以后再次获取锁时,不再有加锁与减锁过程,只是简单判断下获取锁线程是否是当前线程。

轻量级锁:在不同时间段内有不同的线程尝试获取锁
每次锁的获取都需要加锁与解锁过程。

重量级锁:在同一时刻有不同线程尝试获取锁。

锁粗化
将多次连续的加减锁过程粗化为一次大的加减锁过程

public class BigLock {
	private static StringBuffer sb = new StringBuffer();
	public static void main(String[] args) {
		sb.append(“hello”);
		sb.append(“world”);
		sb.append(“test”);
	}
}

锁消除
在没有多线程共同访问的场景下,将锁直接消除。

public class BigLock {
	public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
		sb.append(“hello”);
		sb.append(“world”);
		sb.append(“test”);
	}
}

死锁
死锁的产生原因:以下四个条件同时满足才会产生死锁

  1. 互斥:共享资源X,Y只能被一个线程占用
  2. 占有且等待:线程1已经取得共享资源X,同时在等待资源Y,并且不释放X
  3. 不可抢占:其他线程无法抢占线程1已经占用的资源X
  4. 循环等待:线程1等待线程2的资源,线程2等待线程1的资源

你可能感兴趣的:(新手上路)