powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Годится ли тест для определения существования Spurious wakeups?
4 сообщений из 4, страница 1 из 1
Годится ли тест для определения существования Spurious wakeups?
    #38626210
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вопрос возник по результатам прочтения этой статейки:
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
Годится ли тест для определения существования Spurious wakeups?
    #38626213
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
будит*
...
Рейтинг: 0 / 0
Годится ли тест для определения существования Spurious wakeups?
    #38626227
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
я кажется поняллогику этого человека, но всё равно это ж не 100 процентов.

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

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

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


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