powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Syncronized метод в цикле, большая непонятка
20 сообщений из 20, страница 1 из 1
Syncronized метод в цикле, большая непонятка
    #39493123
Фотография giigro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет всем. Часы курения 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
Syncronized метод в цикле, большая непонятка
    #39493128
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
giigroНе могу понять, почему раскомментировав строку в MyThread1, мы получаем

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

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

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

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

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

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

пойду в Eclipse выполню....
...
Рейтинг: 0 / 0
Syncronized метод в цикле, большая непонятка
    #39493231
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Syncronized метод в цикле, большая непонятка
    #39493253
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsevа причем тут "блокирующее IO". Просто слишком быстро выполняются, переключатся не успевают. IMHO

Сам спросил, сам ответил? В первом случае быстро выполняются. Во втором случае блокируются, поэтому переключаются постоянно.
...
Рейтинг: 0 / 0
Syncronized метод в цикле, большая непонятка
    #39493259
Фотография giigro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Syncronized метод в цикле, большая непонятка
    #39493260
Фотография giigro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Syncronized метод в цикле, большая непонятка
    #39493261
Фотография giigro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сорри за сумбур :) Итоговые пост выглядит так:

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
Syncronized метод в цикле, большая непонятка
    #39493264
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
giigro4. пока поток1 спит, в метод printRatio прибегает поток2 , видит, что он залочен и ожидает, когда его освободит поток1 .
5. поток1 просыпается, делает ratio++ и выходит из метода printRatio, таким образом метод освобождается
6. поток2 заходит в освобожденный метод и повторяется всё с пункта 3.

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

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

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

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

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

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

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

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


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

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

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

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


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