Подтвердить что ты не робот

Выполняются ли одновременно два синхронизированных метода

У меня есть 4 метода (m1, m2, m3 и m4) в классе. Метод m1, m2 и m3 - это методы synchronized. Кроме того, у меня есть 4 потока t1, t2, t3 и t4 соответственно.

Если t1 получить доступ к методу m1 (синхронный метод), может ли метод t2 использовать поток m2 (синхронный метод) одновременно? Если бы не состояние t2?

4b9b3361

Ответ 1

Если t1 получить доступ к методу m1 (синхронный метод), может ли метод t2 потокового доступа m2 (синхронный метод) одновременно?

Ключевое слово synchronized применяется на уровне объекта, и только один поток может удерживать блокировку объекта. Поэтому, пока вы говорите об одном и том же объекте, no, t2 будет ждать t1, чтобы освободить блокировку, полученную при вводе m1.

Однако поток может освободить блокировку, не возвращаясь из метода, вызывая Object.wait().

Если нет, каково будет состояние t2?

Он будет сидеть и ждать t1, чтобы освободить блокировку (возврат из метода или вызов Object.wait()). В частности, он будет находиться в состоянии BLOCKED.

Состояние потока для потока, заблокированного в ожидании блокировки монитора. Нить в заблокированном состоянии ожидает блокировки монитора для ввода синхронизированного блока/метода или повторного входа в синхронизированный блок/метод после вызова Object.wait.

Пример кода:

public class Test {

    public synchronized void m1() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public synchronized void m2() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public static void main(String[] args) throws InterruptedException {
        final Test t = new Test();
        Thread t1 = new Thread() { public void run() { t.m1(); } };
        Thread t2 = new Thread() { public void run() { t.m2(); } };

        t1.start();
        Thread.sleep(500);

        t2.start();
        Thread.sleep(500);

        System.out.println(t2.getState());
    }
}

Вывод:

BLOCKED

Ответ 2

Если методы синхронизируются на одном мониторе, они не могут выполняться одновременно в разных потоках. Когда второй поток приходит к записи монитора (в этом случае запускается синхронизированный метод), он будет блокироваться до тех пор, пока первый поток не освободит монитор.

Фактическое состояние заблокированного потока в этом случае, как сообщается jconsole, будет чем-то вроде java.lang.Thread.State: WAITING (on object monitor)

Предполагая, что все методы являются обычными методами экземпляра, тогда они будут использовать один и тот же монитор при вызове на одном и том же объекте. То есть, если у вас есть что-то вроде:

// Thread 1
A a1 = new A();
a1.m1();

// Thread 2
A a2 = new A();
a2.m2()

то в этом случае второй поток сможет вызвать метод, потому что он пытается получить неявный монитор объекта a2, который не заблокирован потоком 1. Но если поток 2 попытался вызвать a1.m2(), то он будет блокироваться, пока поток 1 не завершит выполнение m1().

Если у вас есть статические методы, они получают явный монитор самого класса (A.class в моем случае с гипотетическим именованием), поэтому он не будет заблокирован вызовами метода экземпляра.

Ответ 3

Нет, не мог. Единственное, что существует для synchronized: разные потоки не могут делать эти вещи одновременно (вам не нужно защищать один поток от них одновременно, потому что один поток не может ничего делать параллельно. ) Состояние ожидающего потока "ждет блокировки". (С достаточно современной JVM вы можете фактически отобразить это состояние на консоли, если вы спросите правильно.)

Ответ 4

Если t1 получить доступ к методу m1 (синхронный метод), может ли метод t2-потока доступа m2 (синхронный метод) одновременно?

Нет. Thread t2 будет ждать, пока Thread t1 освободит блокировку. В том же примере t2 может получить доступ к методу m4, который не синхронизирован.

Замки в synchronized Методы

Каждый объект имеет связанный с ним встроенный замок. По соглашению поток, который нуждается в эксклюзивном и последовательном доступе к полям объекта, должен получить внутреннюю блокировку объекта перед доступом к ним, а затем освободить внутреннюю блокировку, когда она будет выполнена с ними.

Когда поток вызывает синхронизированный метод, он автоматически получает внутреннюю блокировку для этого объекта метода и освобождает его при возврате метода. Блокировка блокировки происходит даже в том случае, если возврат был вызван неперехваченным исключением

Возвращаясь к вашему второму запросу:

Если нет, то каково было бы состояние t2?

Поток t2 находится в заблокированном состоянии и ожидает, пока поток t1 освободит блокировку.

Из java документация:

метод synchronized имеет два эффекта.

Во-первых, невозможно, чтобы две вызовы синхронизированных методов на одном объекте чередовали. Когда один поток выполняет синхронизированный метод для объекта, все другие потоки, которые вызывают синхронизированные методы для одного и того же объекта (приостанавливать выполнение) до тех пор, пока первый поток не будет выполнен с объектом.

Во-вторых, когда синхронизированный метод завершается, он автоматически устанавливает связь между событиями и последующим вызовом синхронизированного метода для одного и того же объекта. Это гарантирует, что изменения состояния объекта видны для всего потока