繁体   English   中英

用Java中的两个线程执行两个同步方法

[英]Executing two synchronized method by two thread in java

可以说我在类ABCsynchronized hi(){}synchronized hello(){}方法的方法。 两个线程t1t2分别执行t1.hi()t2.hello() 它们可以同时执行还是存在任何问题?

否,同一对象中的2个同步方法不能同时执行:

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

从文档:

在同一个对象上两次同步方法调用是不可能交织的。 当一个线程正在执行对象的同步方法时,所有其他调用同一对象块的同步方法的线程(挂起执行),直到第一个线程对该对象完成。

这里的关键是锁定在对象上。 正如Thomas所指出的,大概t1t2是同一类的不同实例,因此它们实际上可以同时执行hi()hello()

如果t1t2仅是在同一对象上调用hi()hello() 2个不同线程,则上述语义成立,并且这2个方法不能并行执行。

在方法声明中使用synced关键字使用隐式对象,对于静态方法,它是类对象;对于非静态方法,是实例对象本身。

范例1:

public class A {
  public synchronized void setName() {
  //
  }

  public synchronized void setAge() {
  //
  }
}

假设有两个线程Thread-1和Thread-2。
现在线程1尝试访问setName()和线程2 setAge()
让线程1输入1st并按住密钥,线程2将等待直到密钥可用。 困惑?
因此,由于没有显式对象用于同步,因此使用相同的密钥来同步两个

“ A的对象,分别用于通过线程1和线程2访问setName()方法和setAge()方法”。

A a = new A("Name", 1);
Runnable nameR = () -> a.getName();
Runnable ageR = () -> a.getAge();
Thread nameThread = new Thread(nameR);
Thread ageThread = new Thread(nameR);
nameThread.start();
ageThread.start();

但这是有问题的,因为即使具有密钥的线程无法访问它,也没有其他线程能够运行其他方法。
因此,要解决此问题,我们需要有单独的键来独立同步getName和getAge方法。

public class A {
private final Object nameLock = new Object();
private final Object ageLock = new Object();
  public void setName() {
   synchronized(nameLock) {
     //
   }
  }

  public synchronized void setAge() {
   synchronized(ageLock) {
     //
   }
  }
}

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM