如果我在同一个类中将两个方法同步了,它们会同时运行吗?
如果我在同一个类中将两个方法同步了,它们会同时运行吗?
如果我在同一个类上对两个方法进行同步,它们能够同时在同一对象上运行吗?例如:
class A { public synchronized void methodA() { //method A } public synchronized void methodB() { // method B } }
我知道我不能在两个不同的线程上同一对象中同时运行methodA()
。同样的情况也适用于methodB()
。
但是我能否在methodA()
仍在运行时在不同的线程上运行methodB()
?(同一对象)
在这个例子中,methodA和methodB都是实例方法(相对于静态方法)。在实例方法上使用synchronized关键字意味着线程必须在执行该方法调用时获取该对象实例的锁(内在锁)才能开始执行任何代码。\n\n如果你有两个不同的实例方法被标记为synchronized,并且不同的线程在同一个对象上同时调用这些方法,这些线程将争夺相同的锁。一旦一个线程获取了锁,所有其他线程都无法进入该对象上的所有同步实例方法。\n\n为了使这两个方法并发运行,它们必须使用不同的锁,像这样:\n\n
class A { private final Object lockA = new Object(); private final Object lockB = new Object(); public void methodA() { synchronized(lockA) { //method A } } public void methodB() { synchronized(lockB) { //method B } } }
\n\n其中同步块语法允许指定执行线程需要获取的特定对象的内在锁才能进入该块。\n\n重要的是要理解的是,即使我们在单个方法上放置\"synchronized\"关键字,核心概念是内在锁在后台起作用。\n\n以下是Java教程描述这种关系的方式:\n\n同步是建立在称为内在锁或监视器锁的内部实体周围的。API规范经常将此实体简单地称为“监视器”。内在锁在同步的两个方面起作用:强制访问对象状态的排他性和建立必要可见性的发生前关系。\n\n每个对象都有与之关联的内在锁。按照惯例,需要独占和一致地访问对象字段的线程在访问它们之前必须取得对象的内在锁,并在完成后释放内在锁。线程在获取锁和释放锁之间拥有内在锁。只要线程拥有内在锁,其他线程就无法获取相同的锁。当其他线程尝试获取锁时,它将被阻塞。\n\n锁的目的是保护共享数据。只有当每个锁保护不同的数据成员时,才会像上面的示例代码中使用分离锁。