Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Годится ли тест для определения существования Spurious wakeups? / 4 сообщений из 4, страница 1 из 1
25.04.2014, 19:26
    #38626210
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Годится ли тест для определения существования Spurious wakeups?
вопрос возник по результатам прочтения этой статейки:
http://www.javenue.info/post/91

приведу код оттуда:

Код: 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.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class TestSpuriousWakeups {
    static final int MAX_THREADS = 6000;

    static final Object mutex = new Object();

    static final CountDownLatch allThreadsStarted =
            new CountDownLatch(MAX_THREADS);
    static final CountDownLatch allThreadsFinished =
            new CountDownLatch(1);

    static final AtomicInteger processedThreads = new AtomicInteger();
    static final AtomicInteger notifiedThreads = new AtomicInteger();

    static volatile boolean continueCondition = true;

    static final Random sleepRandom = new Random();

    static class Worker extends Thread {
        public void run() {
            try {
                synchronized (mutex) {
                    allThreadsStarted.countDown();

                    mutex.wait();
                }

                continueCondition = true;
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                processedThreads.incrementAndGet();
            }
        }
    }

    static class Notifier extends Thread {
        public void run() {
            while (true) {
                // remove block to achieve starvation
                while (!continueCondition)
                    doStuff();

                // all threads finished their execution
                if (processedThreads.get() == MAX_THREADS)
                    break;

                synchronized (mutex) {
                    doStuff();

                    mutex.notify();
                    continueCondition = false;
                    notifiedThreads.incrementAndGet();
                }
            }

            allThreadsFinished.countDown();
        }

        // just to emulate some activity
        void doStuff() {
            try { Thread.sleep(sleepRandom.nextInt(5)); }
            catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < MAX_THREADS; i++)
            new Worker().start();

        // wait for all workers to start execution
        allThreadsStarted.await();

        new Notifier().start();

        // wait for all workers and notifier to finish execution
        allThreadsFinished.await();

        System.out.println("Spurious wakeups count: "
                + (MAX_THREADS - notifiedThreads.get()));
    }
}



как аффтар и обещает, выводится число 0.


Но, если убрать
Код: java
1.
2.
while (!continueCondition)
      doStuff();




из кода метода run класса Notifier, то я почти всегда в выводе вижу отрицательные числа(зачастую они даже в цифру не укладываются - рекорд "-472")

Я не очень понимаю почему если этот блока есть, то всегда всё нормально( 0 выводится)

Ведь у нас такая ситуация - все 600 потоков воркеров уснули.

запускается нотифаер.....входит в sync секцию->будет всех воркеров и они все желают ворваться в sync секцию -> continueCondition = false; -> затем нотифаер покидает sync секцию -> теперь 2 потока

1-
Код: java
1.
2.
3.
4.
5.
6.
7.
while (!continueCondition)
                    doStuff();

                // all threads finished their execution
                if (processedThreads.get() == MAX_THREADS)
                    break;
             synchronized (mutex) {...




2-
Код: java
1.
2.
3.
4.
5.
6.
7.
....
           continueCondition = true;
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                processedThreads.incrementAndGet();
            }



собственно мы не знаем что раньше произойдёт(я так считаю)

doStuff(); может выполниться или не выполниться же.

Соответственно я не понимаю почему в случае наличия этого блока результаты всегда такие одинаковые.

Что я забыл учесть?
...
Рейтинг: 0 / 0
25.04.2014, 19:27
    #38626213
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Годится ли тест для определения существования Spurious wakeups?
будит*
...
Рейтинг: 0 / 0
25.04.2014, 19:52
    #38626227
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Годится ли тест для определения существования Spurious wakeups?
я кажется поняллогику этого человека, но всё равно это ж не 100 процентов.

Как бы так тут элегантно сделать, чтобы после того как как каждый воркер закончит работу следующим секцию занимал именно нотифаер ?
...
Рейтинг: 0 / 0
28.04.2014, 11:35
    #38627551
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Годится ли тест для определения существования Spurious wakeups?
questioner,

Раз все молчат, сам себе отвечу.

Подобной функциональности можно добиться использованием Condition
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Годится ли тест для определения существования Spurious wakeups? / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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