同步是确保多线程对共享资源互斥访问的机制,通过synchronized关键字或Lock接口实现;需合理选择锁对象、缩小同步范围并避免死锁。
同步在 Java 线程中,核心是解决多个线程同时访问共享资源时的数据不一致问题。它不是让线程“一起跑”,而是让它们“轮流用”,确保某一时刻最多只有一个线程能执行关键代码段。
当多个线程操作同一个对象的字段、静态变量或外部资源(如文件、数据库连接)时,若没有同步机制,可能读到中间状态或覆盖彼此的修改。比如两个线程同时对一个 int 计数器执行 i++(实际含读、加、写三步),结果可能只加了一次。
Java 提供两种主要同步手段:
同步方法会把整个方法体作为临界区,锁对象取决于方法类型:
this)MyClass.class)同步代码块更精准,只锁需要保护的那几行代码,并指定锁对象:
synchronized(obj) { /* 只有这里受保护 */ }推荐优先使用同步代码块,避免过度同步影响并发性能。
锁必须是多个线程共同可见且引用一致的对象。常见错误包括:
安全做法:为共享资源定义专用的 private final Object lock = new Object(); 并始终用它同步。
多个线程按不同顺序获取多个锁,就可能互相等待形成死锁。例如线程 A 持有锁1等待锁2,线程 B 持有锁2等待锁1。
避免方式:
部方法(可能隐含其他锁)基本上就这些。理解同步,关键是抓住“谁在争什么资源、用什么锁、锁多久”这三点。