这个问题其实可以理解为在实际开发中,是使用同步代码块好,还是使用同步方法好?
回答这样问题,一定要果断,先肯定,同步代码块比同步方法好,然后我们从三个方面开始说:
1、只需要对临界区的代码进行同步,我们要清楚实际要同步的临界区,大多数情况下,只是某一段需要同步,当然如果整个方法都需要同步,同步代码块和同步方法其实效果是一样的。
2、在同步代码块中,我们可以自由选择锁,同步代码块中,我们可以自由选择任何一个java对象实例为锁,但是同步方法只能是这个对象的实例,这就会带来一个问题,假如我们类中定义了俩个不同的实例同步方法,这俩个方法在业务上并没有太多关联,单例情况下,当某个线程在调用其中一个同步方法时,其他线程就无法调用另外一个实例同步方法,必须等到一个实例同步方法执行完成,释放锁,其他线程才能得到锁,如果我们使用的是同步代码,自由定义锁,这样就可以避免多个同步实例彼此之间的影响。
3、JVM层面的不同
1)同步方法,JVM采用ACC_SYNCHRONIZED标记符来实现同步
a.方法级的同步是隐式的,同步方法的常量池中会有一个ACC_SYNCHRONIZED标志。
b.当某个线程要访问某个方法时,会检测是否有ACC_SYNCHRONIZED,如果有,则需要先获得监视器 锁,然后开始执行方法,方法执行之后再释放监视器锁。
c.这时如果其他线程来请求执行方法,会因为无法获得监视器锁而被阻断
d.如果方法执行过程中,发生异常,并且方法内部没有异常处理,那么在一次呗跑到方法外面之前,监视器锁会被自动释放
2)同步代码块,JVM采用monitorenter、monitorexit两个指令来实现同步
a.可以把执行monitorenter理解为加锁,执行monitorexit理解为释放锁
b.每个对象维护着一个记录着被锁次数的计数器,未被锁定的对象的该计数器为0
c.当一个线程获得锁后,该计数器自增1,当同一个线程再次获得该对象的锁时,计数器再次自增
d.当同一个线程释放锁时,计数器再自减。
e.当计数器为0时,锁被释放,其他线程便可以获得锁
更多关于“Java培训”的问题,欢迎咨询千锋教育在线名师。千锋已有十余年的培训经验,课程大纲更科学更专业,有针对零基础的就业班,有针对想提升技术的好程序员班,高品质课程助理你实现java程序员梦想。