"JAVA并发面试专题:Synchronized的原理及使用"

需积分: 1 1 下载量 145 浏览量 更新于2024-01-31 收藏 1.78MB PDF 举报
Synchronized 相关问题一直是Java面试中必问的题目之一。任何写过并发程序的开发者都应该了解Synchronized并且接触过它。Synchronized是JVM实现的一种互斥同步方式。如果查看被Synchronized修饰过的程序块编译后的字节码,会发现被Synchronized修饰过的程序块在编译前后会被编译器生成monitorenter和monitorexit两个字节码指令。那么这两个指令的作用是什么呢? 在虚拟机执行到monitorenter指令时,首先要尝试获取对象的锁:如果这个对象没有被锁定,或者当前线程已经是该对象的锁的拥有者,则线程可以成功获取该对象的锁,并继续执行后面的操作。如果这个对象被其他线程锁定了,那么线程就会进入到BLOCKED状态,并且该线程会被放入对象的等待队列中,等待其他线程释放锁后再次尝试获取锁。 当一个线程成功获取了对象的锁后,它会执行被Synchronized修饰的代码块。这个代码块在执行过程中,如果发生异常或者执行完毕,都会执行monitorexit指令,该指令会释放对象的锁。在释放锁之后,其他线程就可以竞争获取这个锁。 通过以上的描述可以看出,Synchronized的原理是通过对象的锁机制来实现同步。当一个线程获取到对象的锁后,其他线程就无法进入这个对象的Synchronized代码块,从而保证了同步性。Synchronized的使用可以避免并发程序中的数据竞争和一致性问题。 除了修饰代码块,Synchronized还可以修饰方法和静态方法。当修饰方法时,Synchronized会把整个方法体设为同步代码块,锁对象是当前方法所属对象。当修饰静态方法时,Synchronized会把整个静态方法设为同步代码块,锁对象是当前类的Class对象。 在使用Synchronized的时候,需要注意以下几点: 1. 对Synchronized的使用要小心,过多的同步操作会影响程序的性能。 2. 对于非静态方法,锁对象是当前方法所属对象,如果方法是实例方法,锁的是this对象;如果方法是静态方法,锁的是当前类的Class对象。 3. 对于Synchronized修饰的代码块,锁对象可以是任意对象,但是为了避免歧义,最好选择与数据操作相关的对象作为锁对象。 4. Synchronized不能被继承,如果一个父类的方法是Synchronized修饰的,子类覆写该方法时不能添加Synchronized关键字。 总的来说,Synchronized是Java中用于实现同步的一种方式,通过获取对象的锁来保证多线程间的互斥访问,并避免数据竞争和一致性问题。对于提高并发程序的性能,我们应该合理地使用Synchronized,并注意避免过多的同步操作。