Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Syncronized метод в цикле, большая непонятка / 20 сообщений из 20, страница 1 из 1
21.07.2017, 18:37
    #39493123
giigro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Привет всем. Часы курения stackoverflow результата не принесли, звоню 911спрашиваю здесь. В потоках новичок, поэтому сильно не ругать.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
public class Main {
    public static void main(String[] args) throws InterruptedException {
        threadSafeTest();
    }

    public static void threadSafeTest() throws InterruptedException {
        MyThread1 thread1 = new MyThread1();
        MyThread1 thread2 = new MyThread1();
        thread1.start();
        Thread.currentThread().sleep(250);
        thread2.start();
    }
}

class ThreadSafeSingletone{
    private static final ThreadSafeSingletone instance = new ThreadSafeSingletone();
    private Integer ratio = new Integer(0);
    private ThreadSafeSingletone(){

    }
    public static ThreadSafeSingletone getInstance(){
        return instance;
    }

    public Integer getRatio() {
        return ratio;
    }

    public void setRatio(Integer ratio) {
        this.ratio = ratio;
    }

    public synchronized void printRatio() {
        Integer ratio = getRatio();
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread " + Thread.currentThread().getId() + ": " + ratio + "+1=" + (getRatio() + 1));
        setRatio(getRatio() + 1);
    }
}

class MyThread1 extends Thread{
    private ThreadSafeSingletone singletone = ThreadSafeSingletone.getInstance();
    @Override
    public void run(){
        for(int i = 0; i < 5; i++) {
            //System.out.println("!" + Thread.currentThread().getId());
            singletone.printRatio();
        }
    }
}


Вывод:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Thread 10: 0+1=1
Thread 10: 1+1=2
Thread 10: 2+1=3
Thread 10: 3+1=4
Thread 10: 4+1=5
Thread 11: 5+1=6
Thread 11: 6+1=7
Thread 11: 7+1=8
Thread 11: 8+1=9
Thread 11: 9+1=10


Не могу понять, почему раскомментировав строку в MyThread1, мы получаем
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Thread 10: 0+1=1
Thread 11: 1+1=2
Thread 10: 2+1=3
Thread 11: 3+1=4
Thread 10: 4+1=5
Thread 11: 5+1=6
Thread 10: 6+1=7
Thread 11: 7+1=8
Thread 10: 8+1=9
Thread 11: 9+1=10
...
Рейтинг: 0 / 0
21.07.2017, 18:56
    #39493128
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
giigroНе могу понять, почему раскомментировав строку в MyThread1, мы получаем

Потому что там тоже synchronized метод + блокирющее IO.
...
Рейтинг: 0 / 0
22.07.2017, 01:05
    #39493226
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
thread1.start();
Thread.currentThread().sleep(250);
thread2.start();

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

Не могу понять, почему раскомментировав строку в MyThread1, мы получаем

А в чем проблема? что ожидалось?
...
Рейтинг: 0 / 0
22.07.2017, 01:33
    #39493228
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Ну да, не последовательно.... не очень внимательно посмотрел.

но для эмуляции гонок, тест какой-то больно простой, а лог больно куций.

как минимум вход/выход в ф-цию следовало бы запротоколировать, тогда и вопросов бы не возникло, в каком месте что стоит и в какой последовательности выполняется
...
Рейтинг: 0 / 0
22.07.2017, 01:40
    #39493229
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
вообще не понимаю, что данный код должен делать ((( и что показывать
sleep на sleep'е и sleep'ом погоняет

пойду в Eclipse выполню....
...
Рейтинг: 0 / 0
22.07.2017, 01:54
    #39493231
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Blazkowicz....блокирющее IO.
а причем тут "блокирующее IO". Просто слишком быстро выполняются, переключатся не успевают. IMHO

Ну и потом, какой [нужное вписать, пользуясь своим воображением] тестирует потоки на цикле от 1 до 5 и "удивляется"

Вот на моем компьютере вывод на цикле от 1 до 1000:


Thread 9: 0+1=1
Thread 10: 1+1=2
Thread 10: 2+1=3
Thread 10: 3+1=4
Thread 10: 4+1=5
Thread 10: 5+1=6
Thread 10: 6+1=7
Thread 9: 7+1=8
Thread 9: 8+1=9
Thread 9: 9+1=10
Thread 9: 10+1=11
Thread 9: 11+1=12
Thread 9: 12+1=13
Thread 9: 13+1=14
Thread 10: 14+1=15
Thread 9: 15+1=16
Thread 9: 16+1=17
Thread 10: 17+1=18
Thread 10: 18+1=19
Thread 9: 19+1=20
Thread 10: 20+1=21
Thread 10: 21+1=22
Thread 9: 22+1=23
Thread 10: 23+1=24
Thread 9: 24+1=25
Thread 9: 25+1=26
....
...
Рейтинг: 0 / 0
22.07.2017, 08:02
    #39493253
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Leonid Kudryavtsevа причем тут "блокирующее IO". Просто слишком быстро выполняются, переключатся не успевают. IMHO

Сам спросил, сам ответил? В первом случае быстро выполняются. Во втором случае блокируются, поэтому переключаются постоянно.
...
Рейтинг: 0 / 0
22.07.2017, 09:30
    #39493259
giigro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Leonid KudryavtsevА в чем проблема? что ожидалось?
Без synchrohinzed всё работает предсказуемо:
1. запускается поток1
2. через 250 мс запускается поток2
3. поток 1 запоминает значение ratio=0 и засыпает на 500мс
4. пока поток 1 спит, в метод printRatio прибегает поток2, видит, что он залочен и ожидает, когда его освободит поток2.
5. поток2 просыпается, делает ratio++ и выходит из метода printRatio, таким образом метод освобождается
6. поток1 заходит в освобожденный метод и повторяется всё с пункта 3.

Таким образом, я ожидаю, что в метод printRatio потоки заходят попеременно, что и должно отражаться в логе:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Thread 10: 0+1=1
Thread 11: 1+1=2
Thread 10: 2+1=3
Thread 11: 3+1=4
Thread 10: 4+1=5
Thread 11: 5+1=6
Thread 10: 6+1=7
Thread 11: 7+1=8
Thread 10: 8+1=9
Thread 11: 9+1=10
...
Рейтинг: 0 / 0
22.07.2017, 09:31
    #39493260
giigro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
giigroLeonid KudryavtsevА в чем проблема? что ожидалось?
Без synchrohinzed всё работает предсказуемо:
1. запускается поток1
2. через 250 мс запускается поток2
3. поток 1 запоминает значение ratio=0 и засыпает на 500мс
4. пока поток 1 спит, в метод printRatio прибегает поток2, видит, что он залочен и ожидает, когда его освободит поток2.
5. поток2 просыпается, делает ratio++ и выходит из метода printRatio, таким образом метод освобождается
6. поток1 заходит в освобожденный метод и повторяется всё с пункта 3.

Таким образом, я ожидаю, что в метод printRatio потоки заходят попеременно, что и должно отражаться в логе:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Thread 10: 0+1=1
Thread 11: 1+1=2
Thread 10: 2+1=3
Thread 11: 3+1=4
Thread 10: 4+1=5
Thread 11: 5+1=6
Thread 10: 6+1=7
Thread 11: 7+1=8
Thread 10: 8+1=9
Thread 11: 9+1=10


"Без synchrohinzed" - лишнее,забыл убрать
...
Рейтинг: 0 / 0
22.07.2017, 09:34
    #39493261
giigro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Сорри за сумбур :) Итоговые пост выглядит так:

1. запускается поток1
2. через 250 мс запускается поток2
3. поток1 запоминает значение ratio=0 и засыпает на 500мс
4. пока поток1 спит, в метод printRatio прибегает поток2 , видит, что он залочен и ожидает, когда его освободит поток1 .
5. поток1 просыпается, делает ratio++ и выходит из метода printRatio, таким образом метод освобождается
6. поток2 заходит в освобожденный метод и повторяется всё с пункта 3.

Таким образом, я ожидаю, что в метод printRatio потоки заходят попеременно, что и должно отражаться в логе
...
Рейтинг: 0 / 0
22.07.2017, 09:57
    #39493264
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
giigro4. пока поток1 спит, в метод printRatio прибегает поток2 , видит, что он залочен и ожидает, когда его освободит поток1 .
5. поток1 просыпается, делает ratio++ и выходит из метода printRatio, таким образом метод освобождается
6. поток2 заходит в освобожденный метод и повторяется всё с пункта 3.

Таким образом, я ожидаю, что в метод printRatio потоки заходят попеременно, что и должно отражаться в логе

Да, вот только поток1, (как бы) имеет больший приоритет чем поток2, поэтому система ему даёт возможность добежать до лока и перезахватить его ещё до того как будет разблокирован второй поток. Но данный эффект ничем не гарантируется, поэтому нельзя полагаться на то какой поток захватит лок раньше. Решение нужно строить из того что лок может быть захвачен любым потоком, ведь код до него не синхронизирован.
...
Рейтинг: 0 / 0
22.07.2017, 10:12
    #39493268
giigro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Blazkowicz,

Правильно я понимаю, что добавление строки вывода просто увеличивет шансы перехвата лока другим потоком за счет простоя и из-за этого мы наблюдаем другой лог?
...
Рейтинг: 0 / 0
22.07.2017, 10:29
    #39493272
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
giigroПравильно я понимаю, что добавление строки вывода просто увеличивет шансы перехвата лока другим потоком за счет простоя и из-за этого мы наблюдаем другой лог?
Да, там внутри синхронизация плюс вывод, довольно долгие операции, поэтому система решает (в грубом приближении) разбудить второй поток и дать ему захватить лок.
...
Рейтинг: 0 / 0
22.07.2017, 10:38
    #39493273
giigro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Blazkowicz,
Спасибо!
...
Рейтинг: 0 / 0
22.07.2017, 11:40
    #39493280
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
giigroТаким образом, я ожидаю, что в метод printRatio потоки заходят попеременно, что и должно отражаться в логе.....

Они туда заходят НЕ попеременно, а случайным образом, как бы ОДНОВРЕМЕННО. Если бы Вы запустили цикл не 5 раз, а 100500 раз (а лучше 100500 тысяч раз), Вы бы увидели, что с println, что без println - работает ОДИНАКОВО.

Если время выполнения потока "большое" и он не заблокирован (а Вы его synchornized блокируете) , то шедулер его более равномерно "размазывает".... из-за чего складывается впечатление "попеременно", если время выполнения потоков небольшое (а у Вас это просто приращение +1) - то одновременно может/успевает выполнится целая "пачка" циклов.

IMHO & AFAIK
...
Рейтинг: 0 / 0
22.07.2017, 11:45
    #39493283
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Leonid Kudryavtsev,

Да. Ключевое в данном примере, что порядок может оказаться вообще любым, поэтому рассуждать о порядке выполнения на примере данного кода бессмысленно.
...
Рейтинг: 0 / 0
22.07.2017, 13:44
    #39493295
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
BlazkowiczДа. Ключевое в данном примере, что порядок может оказаться вообще любым, поэтому рассуждать о порядке выполнения на примере данного кода бессмысленно.
Ключевое в данном примере, что цикл от 1 до 5 - это лепет на уровне детского сада

Одна сплошная случайность и никаких закономерностей


Приходит как-то атеист к священнику, и говорит
-Батюшка, а вот ты в Бога веришь.. а как же ты уверен что Он есть.. Доказательства есть?
Священник призадумался.. И говорит
-Ну вот например наш звонарь. Несчастный человек. Грешник, пьет и не может остановиться. Но Богу люб. Зимой с колокольни упал.. Божья благодать его в сугроб направила. Он жив остался. Это ли не чудо?
-Ну это случайность
-Так мало того, он весной с колокольни опять упал.. И опять Божия благодать его в озеро бросила. Снова жив остался!
-Ну.. это совпадение..
Тут вбегает жена священника.. и кричит «Батюшка, наш звонарь опять с колокольни упал! На землю упал!»
Батюшка и атеист в один голос «Что? Помер?»
Жена отвечает.. «Да нет же! Чудо. Жив он!»
Священник торжествует — Ну разве это не чудо Божие.. не доказательство что Бог есть!
Атеист — Неет.. это уже закономерность .
...
Рейтинг: 0 / 0
22.07.2017, 13:57
    #39493298
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
+ бездумно поставленные sleep'ы

я поэтому в первом сообщении на первом же sleep'е и застопорился... дабы нафиг он там не нужен. Если хочется продемонстрировать гонки, то тогда потоки наоборот должны запускаться как можно более одновременно, что бы гонки происходили чаще.

ну и отладочная печать явно не достаточна, т.к. совершенно ничего не показывает. Ни что потоки выполняются одновременно, ни что они стоят на synchronized. В общем, в качестве демонстрационного примера, код крайне не удачный.

Ну а предположение "попеременно" - это какая-то больная фантазия. Потоки НЕ выполняются "попеременно", они выполняются ОДНОВРЕМЕННО. В данном случае, ошибка из серии "первое попавшиеся не попало" (первые 5 итераций цикла по случайности / чуду, выполнились последовательно)
...
Рейтинг: 0 / 0
22.07.2017, 17:17
    #39493347
giigro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Leonid Kudryavtsevне очень внимательно посмотрел.
Вы и вправду не очень внимательно смотрите. Я сразу написал, что новичок. Да, все верно, детский лепет. А вы, не умея говорить, сразу начинали декламировать сонэты, сэр? Указываете мне тут на больную фантазию, закатываете глаза как барышня. Не спортивно и не круто. Фу.
...
Рейтинг: 0 / 0
22.07.2017, 17:22
    #39493350
giigro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Syncronized метод в цикле, большая непонятка
Blazkowicz расставил всё по местам двумя постами, спасибо вам ещё раз.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Syncronized метод в цикле, большая непонятка / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]