powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Как бороться со starvation ?
15 сообщений из 15, страница 1 из 1
Как бороться со starvation ?
    #38625833
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Читал про deadlock livelock starvation.

Про первые два всё вроде понял, а про starvation как-то не до конца.

Я так понял, что так как synchronized секцию захватывает тот, кому больше повезло, то возможно ситуация, что потокам неудачникам придётся вечно ждать своей очереди. Но так чтобы описывалось какое-то решение этой проблемы я как-то не нашёл.

Сам полагаю, что ReentrantLock с fair=true поможет.

Может эта проблема ещё как-то по другому решается ?
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38625839
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде первые ссылки из гугла подробно разжевывают.
http://tutorials.jenkov.com/java-concurrency/starvation-and-fairness.html
Всё зависит от причин starvation. В случае блокировок fairness это решение. В случае борьбы на CPU это, например, yield().
Ну, и, по-моему, операционная система и JVM тоже стараются следить за тем чтобы минимизировать starvation даже без явного fairness. Так как fair lock требует больше ресурсов.
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38625872
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,


я просто туториалы этого кудесника не читаю после того как очень долго пытался понять, что он про семафоры пишет.

http://tutorials.jenkov.com/java-concurrency/semaphores.html#assignal
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38625877
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerя просто туториалы этого кудесника не читаю после того как очень долго пытался понять, что он про семафоры пишет.
http://tutorials.jenkov.com/java-concurrency/semaphores.html#assignal
И что не так с семафором?
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38625889
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

Код: 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.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
public class SendReceiveWithCustomSemaphore {
    public static void main(String[] args) {
        MySemaphore mySemaphore = new MySemaphore();
        new Send(mySemaphore).start();
        new Receive(mySemaphore).start();
    }
}

class MySemaphore {
    boolean flag = false;

    public synchronized void take() throws InterruptedException {
        flag = true;
        notify();
    }

    public synchronized void release() throws InterruptedException {
        while (!flag) {
            wait();
        }
        flag = false;
    }
}

class Send extends Thread {
    MySemaphore mySemaphore;

    public Send(MySemaphore semaphore) {
        this.mySemaphore = semaphore;
    }

    @Override
    public void run() {
        int i = 0;
        while (i++ < 10) {
            System.out.println("send");
            try {
                mySemaphore.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Receive extends Thread {
    MySemaphore mySemaphore;

    public Receive(MySemaphore semaphore) {
        this.mySemaphore = semaphore;
    }

    @Override
    public void run() {
        while (true) {
            try {
                mySemaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("receive");
        }
    }
}



вроде по его канонам код написан, а выводит

авторsend
send
send
send
send
send
send
send
send
send
receive


я так понял, что должно быть

send -receive
send -receive
send -receive
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38626048
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
questioner ,
Очень важно понимать, что starvation это не особенность какого-то инструмента (напр. synchronized, или ReentrantLock). Starvation - это логическая проблема, которая заключается в том, что поток не может получить доступ к какому-либо ресурсу. Причин этому может быть масса. Два примера, как можно эмулировать starvation в "домашних условиях":
1) Берете ReentrantReadWriteLock. Стартуете 10 потоков, которые в бесконечном цикле берут readLock через ReadWriteLock.readLock().tryLock(), потом спят 50 миллисекунд, потом отпускают ее. И так бесконечно. И потом стартуете один поток, которые пробует взять writeLock через ReadWriteLock.writeLock().lock(). Вы увидите, что write lock никогда не будет захвачен. Это starvation. Теперь меняете одну единственную строчку: readLock().tryLock() на readLock().tryLock(0, TimeUnit.MILLISECONDS) - все, starvation больше нет. Природа этого starvation - высокая агрессивность tryLock(), который игнорирует даже fair flag.
2) Создаете однопоточный ThreadPoolExecutor. Создайте CountDownLatch(1). Сабмитим в экзекьютор джобу, которая 1) сабмитит в этот же пул вторую джобу, 2) Ждет latch.await(). А вторая джоба, в свою очередь, вызвает latch.countDown(). Все, вторая джоба у вас попала в starvation, из которого никогда не выйдет. Природа - нет места в экзекьюторе.
И таких примеров можно придумать массу. Как видите, природа того или иного starvation может быть совершенно разной, и бороться с ними надо по-разному. Универсального рецепта нет.

Что касается Thread.yield() - сможете ли вы им решить описанные выше проблемы? Разумеется, нет. Я уже писал выше - этот метод на практике почти не используется. Во-первых, почитайте его JavaDoc - конкретные JVMки могут вообще его игнорировать. Во-вторых, современные планировщики нормально раздают кванты времени потокам. Никто не останется ущимленным. Особенно учитывая тот факт, что в Java запрещено менять приоритеты потоков. Что бы убедиться в этом, запустите следующую программу:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public static void main(String[] args) {
	for (int i = 0; i < 100; i++) {
		final int i0 = i;

		new Thread(new Runnable() {
			@Override public void run() {
				while (true) {
					System.out.println(i0);
				}
			}
		}).start();
	}
}


Вы увидите, что все потоки переключаются нормально, никто не впадает в starvation. А потом добавьте внутрь цикла while Thread.yield(). Что-нибудь изменилось? Неа. Поэтому в 99% Thread.yield() никак вам не поможет, ибо планировщики не позволят какому-либо потоку монопольно зянать ядро на длительное время.
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38626059
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, и по поводу fairness. Здесь необходимо четко понимать, каковы последствия использования или не использования этого флажка. Во-первых, если Lock у вас занимается/освобождается не слишком часто, и нету чего-то вроде
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
while (true) {
    lock.lock()
	
	try {
	    ...
	} finally {
	    lock.unlock()
	}
}


... то у вас итак потоки будут выполняться в приблизительно том порядке, в котором они попросили lock. Это следует из имплементации ReentrantLock. Во-вторых, fair локи под нагрузкой становятся оооочень медленными. Non-fair режим - это главный козырь Lock по сравнению с synchronized. Именно он делает их более предпочтительными под нагрузкой. Если же вы ставите fair режим, то вы становитесь на два порядка медленнее non-fair, и на порядок медленнее synchronized. Стоит ли оно того - решать вам. Наконец, у нас проекте просто невероятное количество ReentrantLock и ReentrantReadWriteLock. Ни разу нам не пришлось использовать fair режимы. Ни разу. Так как у этого режима настолько узкая примемнимость, и настолько мало случаев, когда реально возникает непредумышленный starvation именно на захвате лока, что очень сложно попасть на такую ситуацию, когда fair режим реально что-то даст.
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38626204
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DEVcoachЯ уже писал выше - этот метод на практике почти не используется.
Вы принципиально не читаете что другие пишут?
15917980
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38626526
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

так что по поводу семафоров?

я туплю?
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38627535
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DEVcoach,

DEVcoachБерете ReentrantReadWriteLock. Стартуете 10 потоков, которые в бесконечном цикле берут readLock через ReadWriteLock.readLock().tryLock(), потом спят 50 миллисекунд, потом отпускают ее. И так бесконечно. И потом стартуете один поток, которые пробует взять writeLock через ReadWriteLock.writeLock().lock(). Вы увидите, что write lock никогда не будет захвачен. Это starvation. Теперь меняете одну единственную строчку: readLock().tryLock() на readLock().tryLock(0, TimeUnit.MILLISECONDS) - все, starvation больше нет. Природа этого starvation - высокая агрессивность tryLock(), который игнорирует даже fair flag.


Но ведь на одной машине будет starvation, на другой нет я полагаю, ну то есть это не 100%. Как например в таком случае написать код так, чтобы starvation гарантированно не было ? это возможно?
DEVcoach Non-fair режим - это главный козырь Lock по сравнению с synchronized. Именно он делает их более предпочтительными под нагрузкой. Если же вы ставите fair режим, то вы становитесь на два порядка медленнее non-fair, и на порядок медленнее synchronized.

А можете поподробнее немного? я про производительность никогда и не думал.

Blazkowicz, что значит Ваше молчание ?
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38627564
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerBlazkowicz, что значит Ваше молчание ?
Мне лень разбираться с той статьёй чтобы ответить. Там, действительно, не понятно где он свой семафор использует, а где API. Но из приведенного кода и вашего примера, результат вполне логичный и ожидаемый, поэтому мне не понятно что вызывает затруднение.
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38627584
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

да, согласен, что вывод кода вполне ожидаемый. Затруднение в том, что это первое, что я читал про семафоры. И это слегка вынесло мне мозг.
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38627586
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerКак например в таком случае написать код так, чтобы starvation гарантированно не было ? это возможно?
как-то так
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38631297
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DEVcoach,

Что-нибудь ответите по поводу http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1091315&msg=15945224 ? все сравнения, что я встречал не касались проиводительности.
...
Рейтинг: 0 / 0
Как бороться со starvation ?
    #38631428
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
redwhite90 ,
Что бы понимать перфоманс ReentrantLock надо знать, как она устроена изнутри. Есть два отличных способа это узнать:
1) Почитать статью Дага Ли, который ее разрабатывал: http://gee.cs.oswego.edu/dl/papers/aqs.pdf
2) Почитать исходники AbstractQueuedSynchronizer.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Как бороться со starvation ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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