并发编程之synchronize

214 阅读1分钟

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个线程交替访问

重量级锁:多线程并发访