She*_*lef 143 java multithreading synchronized java-threads
如果我在同一个类上同步两个方法,它们可以同时在同一个对象上运行吗?例如:
class A {
public synchronized void methodA() {
//method A
}
public synchronized void methodB() {
// method B
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我不能methodA()在两个不同的线程中对同一个对象运行两次.同样的事情methodB().
但是,在运行methodB()时我可以在不同的线程上methodA()运行吗?(同一个对象)
NPE*_*NPE 134
两种方法都锁定同一台显示器.因此,您不能在不同线程的同一对象上同时执行它们(两个方法中的一个将阻塞,直到另一个完成).
Nat*_*hes 101
在示例中,methodA和methodB是实例方法(与静态方法相对).把synchronized上一个实例方法意味着该线程必须获取关于对象实例锁(以下简称"本征锁"),该方法被称为在线程之前可以开始在该方法中执行的任何代码.
如果您有两个标记为synchronized的不同实例方法,并且不同的线程在同一个对象上同时调用这些方法,那么这些线程将争用同一个锁.一旦一个线程获得锁定,所有其他线程就会被该对象上的所有同步实例方法关闭.
为了使两个方法同时运行,它们必须使用不同的锁,如下所示:
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
其中synchronized块语法允许指定执行线程需要获取内部锁定的特定对象才能进入块.
要理解的重要一点是,即使我们在单个方法上放置"同步"关键字,核心概念也就是幕后的内在锁定.
以下是Java教程描述关系的方式:
同步是围绕称为内部锁或监视器锁的内部实体构建的.(API规范通常将此实体简称为"监视器".)内部锁在同步的两个方面都发挥作用:强制对对象状态进行独占访问,并建立对可见性至关重要的先发生关系.
每个对象都有一个与之关联的内在锁.按照惯例,需要对对象字段进行独占和一致访问的线程必须在访问对象之前获取对象的内部锁,然后在完成它们时释放内部锁.据说一个线程在获得锁定和释放锁定之间拥有内在锁定.只要一个线程拥有一个内部锁,没有其他线程可以获得相同的锁.另一个线程在尝试获取锁时将阻塞.
锁定的目的是保护共享数据.只有在每个锁保护不同的数据成员时,才会使用上面示例代码中所示的单独锁.
Sri*_*nth 15
Java Thread 在进入实例同步java方法时获取对象级锁,并在进入静态同步java方法时获取类级锁.
在您的情况下,方法(实例)属于同一类.因此,当线程进入java synchronized方法或块时,它获取一个锁(调用该方法的对象).因此,在完成第一个方法并释放lock(on object)之前,不能在同一个对象上同时调用其他方法.
Ole*_*_DJ 12
在您的情况下,您在同一个类实例上同步了两个方法.因此,这两个方法不能同时在同一个A类实例的不同线程上运行.但它们可以在不同的A类实例上运行.
class A {
public synchronized void methodA() {
//method A
}
}
Run Code Online (Sandbox Code Playgroud)
是相同的:
class A {
public void methodA() {
synchronized(this){
// code of method A
}
}
}
Run Code Online (Sandbox Code Playgroud)
将您的代码视为以下代码:
class A {
public void methodA() {
synchronized(this){
//method A body
}
}
public void methodB() {
synchronized(this){
// method B body
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在方法级别同步仅表示已同步(此)。如果有任何线程运行此类的方法,它将在开始执行之前获取该锁,并保持该锁直到该方法的执行完成。
但是,当methodA()仍在运行时,我可以在其他线程上运行methodB()吗?(相同的对象)
确实,这是不可能的!
因此,多个线程将无法在同一对象上同时运行任何数量的同步方法。