Кто может объяснить принцип работы

436
16 июня 2017, 08:25

Есть код

public class Solution {
public void someMethodWithSynchronizedBlocks(Object obj1, Object obj2) {
    int lock1 = obj1.hashCode();
    int lock2 = obj2.hashCode();
    Object firstLock = lock1 > lock2 ? obj1 : obj2;
    Object secondLock = lock1 > lock2 ? obj2 : obj1;
    synchronized (firstLock) {
        try {
            Thread.sleep(100);
        } catch (InterruptedException ignored) {
        }
        synchronized (secondLock) {
            System.out.println(obj1 + " " + obj2);
        }
    }
}
public static boolean isNormalLockOrder(final Solution solution, final Object o1, final Object o2) throws Exception {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            synchronized (o2) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    thread.start();
    Thread thread1 = new Thread(new Runnable() {
        @Override
        public void run() {
            synchronized (o2) {
                solution.someMethodWithSynchronizedBlocks(o1, o2);
            }
        }
    });
    thread1.start();
    System.out.println(thread.getState());
    System.out.println(thread1.getState());
    return Thread.State.BLOCKED.equals(thread1.getState());
}
public static void main(String[] args) throws Exception {
    final Solution solution = new Solution();
    final Object o1 = new Object();
    final Object o2 = new Object();
    System.out.println(isNormalLockOrder(solution, o1, o2));
}
}

Задание было такое

Реализуй логику метода isNormalLockOrder, который должен определять:

соответствует ли порядок synchronized блоков в методе someMethodWithSynchronizedBlocks — порядку передаваемых в него аргументов.

В случае, если сначала происходит синхронизация по o1, а потом по o2, метод должен вернуть true.

Если наоборот — false.

Вопрос вот в чем, задание принято, то есть правильно выполнено, но, оно как я понял не работает у меня корректно, да и вообще не понятно. Кто может пояснить, почему блокируется только synchronized (o2)?

Answer 1

Во-первых для проверки правильности на тесте добавьте в метод someMethodWithSynchronizedBlocks(Object obj1, Object obj2) строку System.out.println("must be "+ (obj1.hashCode()>obj2.hashCode())); Вы увидите что иногда результат работы вашего метода проверки будет неверен.

Во-вторых, если вы сказали потоку thread.start() это еще совсем не значит что он успел стартануть до того как начал выполняться код в основном потоке. Запросто может быть ситуация когда он вообще стартанет после того как основной поток завершит работу. И вообще, может быть такая ситуация что оба новых потока вообще не успеют начать работу до того как закончит работу основной поток. Поэтому лучше снова перерешать задание.

Answer 2

Даже не знаю как объяснить, первоначально при получение задания код такой

public class Solution {
public void someMethodWithSynchronizedBlocks(Object obj1, Object obj2) {
    synchronized (obj1) {
        synchronized (obj2) {
            System.out.println(obj1 + " " + obj2);
        }
    }
}
public static boolean isNormalLockOrder(final Solution solution, final Object o1, final Object o2) throws Exception {
    //реализуйте метод
    return false;
}
public static void main(String[] args) throws Exception {
    final Solution solution = new Solution();
    final Object o1 = new Object();
    final Object o2 = new Object();
    System.out.println(isNormalLockOrder(solution, o1, o2));
}

}

а задание вот:

Определяем порядок захвата монитора

Реализуй логику метода isNormalLockOrder, который должен определять:

соответствует ли порядок synchronized блоков в методе someMethodWithSynchronizedBlocks — порядку передаваемых в него аргументов.

В случае, если сначала происходит синхронизация по o1, а потом по o2, метод должен вернуть true.

Если наоборот — false.

Требования:

1. Метод isNormalLockOrder должен возвращать true в случае, если синхронизация в методе someMethodWithSynchronizedBlocks происходит сначала по объекту o1, а потом по o2.

2. Метод isNormalLockOrder должен возвращать false в случае, если синхронизация в методе someMethodWithSynchronizedBlocks происходит сначала по объекту o2, а потом по o1.

3. Метод isNormalLockOrder НЕ должен быть приватным.

4. Класс Solution НЕ должен быть объявлен с модификатором final.

READ ALSO
К какому типу кодирования относится эта binary строчка(а именно рус буквы)

К какому типу кодирования относится эта binary строчка(а именно рус буквы)

При разборе binary файла столкнулся с тем, что в binary файле есть русские буквы и как их разобрать не знаюв первых скобках написано в десятичном...

272
JavascriptInterface как обратиться к встроенным интерфейсам WebView

JavascriptInterface как обратиться к встроенным интерфейсам WebView

Всем приветЯ хочу из своего js интерфейса обратится к интерфейсу ну например document или чему-то подобному, а как это сделать незнаю

304
Android Pre Dex: [mysql-connector-java-5.1.6.jar] Exception in thread

Android Pre Dex: [mysql-connector-java-5.1.6.jar] Exception in thread

Закоммитился - нормальноПосле обновления с свн, при компиляции начал получать несовсем понятный мне exception, причем ругается не только на mysql-connector,...

506