synchronize的基本用法
private int count = 10;
private Object o = new Object();
public void m() {
synchronized(o) { //任何线程要执行下面的代码,必须先拿到o的锁
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}
private int count = 10;
public void m() {
synchronized(this) { //任何线程要执行下面的代码,必须先拿到this的锁
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}
private int count = 10;
public synchronized void m() { //等同于在方法的代码执行时要synchronized(this)
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
private static int count = 10;
public synchronized static void m() { //这里等同于synchronized(FineCoarseLock.class)
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
synchronize锁的可重入性
对于同一个线程来说,锁的是同一个对象,那么可以调用
异常和锁
程序执行中,如果出现异常,默认情况下锁会被释放
synchronize底层实现
synchronize锁对象头两位,synchronize的升级过程,先是无锁,接下来有线程访问sync(Object) MarkWord会记录线程的ID (偏向锁)
如果线程争用就会升级为自旋锁,自旋10次之后,还得不到锁,升级为重量级锁(系统级别锁)
无锁:无线程个数约束,没有synchronized、lock修饰/做同步控制
偏向锁:只有一个线程访问
轻量级锁:2个线程交替访问
重量级锁:多线程并发访