Java synchronized详解:多线程协调与轻重锁机制

需积分: 0 0 下载量 196 浏览量 更新于2024-08-04 收藏 259KB DOCX 举报
Java中的`synchronized`关键字是实现线程同步的关键,尤其是在多线程环境下确保数据访问的正确性和避免竞态条件的重要手段。在Java中,`synchronized`用于控制对特定代码块或方法的并发访问,确保同一时刻只有一个线程能够执行被锁定的代码。 当我们使用`synchronized`修饰一个类的公共方法(如题目中提到的`func`),这意味着对这个方法的执行会被自动地进行线程同步。这意味着在任何时刻,最多只有一个线程可以持有该方法的锁,其他尝试访问该方法的线程将会阻塞,直到当前线程完成方法执行并释放锁。 在Java中,锁实际上是存储在对象的元数据(MarkWord)中,特别是轻量级锁阶段。当两个线程尝试并发地执行对同一对象使用`synchronized`的方法时,如果没有造成过多的上下文切换,系统会使用轻量级锁,这是一种基于 monitors 的机制。当竞争变得严重时,轻量级锁会升级为重量级的ObjectMonitor,这个过程涉及entrySet、Owner和waitSet的概念: - `entrySet`:类似大楼的大厅,所有进入 Monitor 的线程都会在这里排队。 - `Owner`:当前持有锁并执行方法的线程,负责管理其他线程的等待和唤醒。 - `waitSet`:当Owner调用`wait`方法时,线程会进入此集合,等待被唤醒。 当线程试图获取锁时,它会首先检查`entrySet`是否为空且没有其他线程是Owner。如果是,它会成为新的Owner并进入方法执行。如果Owner正在执行,那么其他线程需要等待,直到Owner调用`notify`或`notifyAll`来唤醒一个或多个等待的线程。 面试中,许多Java开发者可能会忽视这一点,误认为`synchronized`方法的并发性意味着线程可以同时运行。实际上,这是错误的,因为`synchronized`确保的是在特定方法或代码块内部的互斥访问,而不是整个类的实例。因此,即使有两个实例`a1`和`a2`,它们各自的`synchronized`方法`func`仍会以独占的方式执行,确保了线程间的有序性。 总结来说,理解Java的`synchronized`关键字对于确保多线程环境下的代码正确性至关重要,它通过控制锁的获取和释放,以及利用entrySet、Owner和waitSet等概念,实现了线程之间的协作与同步。掌握这些原理有助于开发者编写健壮的并发代码,并避免常见的并发问题。