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

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

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

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

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


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

http://tutorials.jenkov.com/java-concurrency/semaphores.html#assignal
...
Рейтинг: 0 / 0
25.04.2014, 15:29
    #38625877
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
questionerя просто туториалы этого кудесника не читаю после того как очень долго пытался понять, что он про семафоры пишет.
http://tutorials.jenkov.com/java-concurrency/semaphores.html#assignal
И что не так с семафором?
...
Рейтинг: 0 / 0
25.04.2014, 15:34
    #38625889
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
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
25.04.2014, 16:58
    #38626048
DEVcoach
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
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
25.04.2014, 17:06
    #38626059
DEVcoach
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
Да, и по поводу 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
25.04.2014, 19:22
    #38626204
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
DEVcoachЯ уже писал выше - этот метод на практике почти не используется.
Вы принципиально не читаете что другие пишут?
15917980
...
Рейтинг: 0 / 0
26.04.2014, 14:13
    #38626526
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
Blazkowicz,

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

я туплю?
...
Рейтинг: 0 / 0
28.04.2014, 11:30
    #38627535
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
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
28.04.2014, 11:44
    #38627564
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
questionerBlazkowicz, что значит Ваше молчание ?
Мне лень разбираться с той статьёй чтобы ответить. Там, действительно, не понятно где он свой семафор использует, а где API. Но из приведенного кода и вашего примера, результат вполне логичный и ожидаемый, поэтому мне не понятно что вызывает затруднение.
...
Рейтинг: 0 / 0
28.04.2014, 11:55
    #38627584
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как бороться со starvation ?
Blazkowicz,

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

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


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