Java多线程同步Synchronized详解:实例与类对象的锁定

0 下载量 166 浏览量 更新于2024-08-29 收藏 45KB PDF 举报
Java多线程同步机制是Java并发编程中的核心概念,它主要用来解决多个线程访问共享资源时可能出现的数据安全问题。Synchronized关键字是Java提供的一种内置锁机制,用于控制多线程对共享资源的访问,确保同一时刻只有一个线程能够执行特定的代码块。 **同步方法与同步块** 1. **同步方法**:在Java中,我们可以在方法声明前加上`synchronized`关键字,这会使得该方法成为一个同步方法。当一个线程进入同步方法后,其他试图调用该方法的线程必须等待当前线程完成方法执行后才能继续。例如,`public synchronized void m1()` 就是一个同步方法,锁定的对象是该方法所属的类实例。 2. **同步块**:同步块(也称为同步语句块)更具有针对性,允许我们锁定一个特定的对象。语法形式为 `synchronized(object) { ... }`,其中`object`是你要锁定的对象。这样,只有获取到`object`锁的线程才能执行同步块内的代码。例如,`synchronized(a) { ... }` 锁定的是对象`a`。 **同步锁定的内容** 无论同步方法还是同步块,它们锁定的都是一个对象。对于非静态成员(实例变量),锁定的是该成员所属的对象实例。而对于静态成员(类变量),锁定的是类的Class对象,即所有类实例共享的锁。这意味着,对于不同实例对象,它们的非静态成员可以分别被不同的线程同步访问,而静态成员则是全局唯一的,所有线程共享同一把锁。 **同步的原因** - 当一个类的多个实例需要通过多线程访问时,如果存在类变量或者有共享资源的访问,同步是必要的,以避免数据不一致性和资源竞争问题。 - 对于公共资源的读写操作,如文件、数据库连接等,同步能够保证在同一时刻只有一个线程进行操作,防止数据混乱。 **示例分析** 在给定的示例中,展示了不同情况下同步的效果: 1. **同步方法示例**:在`Demo1`类中,`m1`和`m2`方法的同步都是针对类实例对象的。如果两个线程`thread1`和`thread2`分别调用不同实例`demo1`和`demo2`的`m1`方法,它们可以并行执行,因为锁是针对实例的。但如果一个线程调用`m1`,另一个线程尝试访问同一个实例的`m2`,它们会被阻塞,直到持有锁的线程完成。 2. **同步块示例**:在`Demo2`类中,`m1`和`m2`方法的同步是针对不同对象`a`和`b`的。这意味着即使两个线程同时调用`m1`和`m2`,只要它们锁定的是不同的对象,就可以并发执行。然而,如果两个线程都在`m1`中锁定`a`,则它们会被互斥执行。 总结来说,Java中的`synchronized`关键字是实现线程同步的关键,它可以确保多线程环境中的数据一致性,防止竞态条件。合理地使用同步,能够有效提升程序的并发性能和安全性。