Нет они не могут выполняться параллельно на одном и том же сервисе - оба метода используют один и тот же монитор (т. Е. this
), и поэтому, если поток A выполняет calc1
, поток B выигралне сможет получить монитор и не сможет запустить calc2
.(Обратите внимание, что поток B мог бы вызвать любой метод для другого экземпляра из Service
, хотя, поскольку он будет пытаться получить другой, не удерживаемый монитор, так как рассматриваемый this
будет другим.)
Самое простое решение (если вы хотите, чтобы они работали независимо), было бы сделать что-то вроде следующего, используя явные мониторы:
class Service {
private final Object calc1Lock = new Object();
private final Object calc2Lock = new Object();
public void calc1() {
synchronized(calc1Lock) {
// ... method body
}
}
public void calc2() {
synchronized(calc2Lock) {
// ... method body
}
}
}
Рассматриваемые "блокировки" не должныиметь какие-либо особые способности, кроме того, чтобы быть объектами, и, следовательно, иметь определенный монитор.Если у вас есть более сложные требования, которые могут включать попытки немедленно заблокировать и откатиться назад, или запросить, кто держит блокировку, вы можете использовать фактические Lock объекты, но для базового случая этопростые Object
замки в порядке.