Java中的关键字Synchronized的一些问题

Synchronized关键字加锁加在哪里

Synchronized关键字可以指定加锁的对象,也可以不指定直接使用。

  1. synchronized关键字通过使用monitorenter和monitorexit两个字节码指令,来完成对对象的锁定。前者令锁计数器+1,后者令锁计数器-1。当锁计数器为0的时候,表示当前没有任何线程在访问本对象的同步方法。
  2. 对于非静态方法,当关键字不指定加锁的对象的时候,锁默认加在这个同步方法所在的对象上边。也就是说,同一个对象在两个线程中分别访问该对象的两个同步方法,会产生互斥。当然如果这个对象当中的一些方法并没有使用synchronized关键字,那么仍然可以并发访问。
  3. 当关键字指定了加锁对象的时候,只有访问同一个对象所管理的Synchronized段,才会发生互斥。
  4. 对于静态方法,锁默认加在这个类对象上。注意类本身也是一个对象,也就是说静态方法的同步段,只和静态的类有关。

Synchronized关键字的使用注意事项

  1. 如果要写清加锁对象的话,那么一般,这个对象需要被修饰成final,因为如果这个对象不是final类型,可能某个线程加锁之后,有别的线程更改了这个对象的引用指向,此时这个线程再去访问synchronized的临界区,仍然可以继续访问,因为此时两个锁加在了不一样的地址上。
  2. synchronized关键字生效的区域,应该在满足要求的情况下尽可能小,因为同步区域会讲并行操作转化为串行操作。根据并行加速公式

    Java中的关键字Synchronized的一些问题_第1张图片

    即便只有10%的代码无法并行计算,哪怕系统中的并行计算单元是无穷的,最多也只能加速10倍。考虑到同步区域还要对外保持的一些特性,比如禁止重排序等,这个数字可能并不是很难达到,糟糕的代码会使得多线程的意义全无

你可能感兴趣的:(Java中的关键字Synchronized的一些问题)