Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Потоки, некоторая непонятка


Автор: soulcub 9.7.2010, 11:40
Нашёл, как по мне, неплохой пример по приоритетам потоков.

Код

public class ThreadTest implements Runnable {

    public void run() {
        double calc;
        for (int i = 0; i < 50000; i++) {
            calc = Math.sin(i * i);
            if (i % 10000 == 0) {
                System.out.println(getName()
                        + " counts " + i / 10000);
            }
        }
    }

    public String getName() {
        return Thread.currentThread().getName();
    }

    public static void main(String s[]) {
        // Подготовка потоков
        Thread t[] = new Thread[3];
        for (int i = 0; i < t.length; i++) {
            t[i] = new Thread(new ThreadTest(),
                    "Thread " + i);
        }
        // Запуск потоков
        for (int i = 0; i < t.length; i++) {
            t[i].start();
            System.out.println(t[i].getName()
                    + " started");
        }
    }
}


и в том же примере написано, что в данном случае, без приоритетов потоки запускаются по-очереди и выполняются так же. 
То-есть на экране мы увидим нечто такое:

Thread 0 started
Thread 1 started
Thread 2 started
Thread 0 counts 0
Thread 1 counts 0
Thread 2 counts 0
Thread 0 counts 1
Thread 1 counts 1
Thread 2 counts 1
Thread 0 counts 2
Thread 2 counts 2
Thread 1 counts 2
Thread 2 counts 3
Thread 0 counts 3
Thread 1 counts 3
Thread 2 counts 4
Thread 0 counts 4
Thread 1 counts 4 

По логике так и должно происходить, но у меня получается некий непонятный бред, который не поддаётся моей логике..
Выводит:

Thread 0 started
Thread 1 started
Thread 2 started
Thread 1 counts 0
Thread 1 counts 1
Thread 1 counts 2
Thread 0 counts 0
Thread 1 counts 3
Thread 0 counts 1
Thread 1 counts 4
Thread 0 counts 2
Thread 0 counts 3
Thread 2 counts 0
Thread 2 counts 1
Thread 0 counts 4
Thread 2 counts 2
Thread 2 counts 3
Thread 2 counts 4

в другой раз такое:

Thread 0 started
Thread 0 counts 0
Thread 1 started
Thread 2 started
Thread 1 counts 0
Thread 2 counts 0
Thread 0 counts 1
Thread 2 counts 1
Thread 0 counts 2
Thread 2 counts 2
Thread 0 counts 3
Thread 2 counts 3
Thread 0 counts 4
Thread 2 counts 4
Thread 1 counts 1
Thread 1 counts 2
Thread 1 counts 3
Thread 1 counts 4

Не могу понять в чём прикол. Есть догадка, что это связано с тем, что у меня проц двухядерный. 
Но почему оно действует именно так? Спасибо заранее.

Автор: AbdulBcex 9.7.2010, 12:14
Вообще по логике потокам присваиватся приоритет потока их породившего. То есть в этом примере у всех потоков приоритет один и одинаков, следовательно распределение ресурсов может происходить каждый раз совершенно по разному и могут быть разные результаты. 
Цитата

и в том же примере написано, что в данном случае, без приоритетов потоки запускаются по-очереди и выполняются так же. 

Кстати, в книгах обычно наоборот пишут, что результаты различаться могут.

Автор: soulcub 9.7.2010, 13:08
Ну ок, логика есть. Но если делаю приоритетом(немного поменяю мейн)

Код

    public static void main(String s[]) {
        // Подготовка потоков
        Thread t[] = new Thread[3];
        for (int i = 0; i < t.length; i++) {
            t[i] = new Thread(new ThreadTest(),
                    "Thread " + i);
        }
        t[0].setPriority(Thread.MIN_PRIORITY);
        t[1].setPriority(Thread.NORM_PRIORITY);
        t[2].setPriority(Thread.MAX_PRIORITY);
        // Запуск потоков
        for (int i = 0; i < t.length; i++) {
            t[i].start();
            System.out.println(t[i].getName()
                    + " started");
        }
    }


тут же должно быть отчётливое доминирование 2-го над 1-м, и их обоих над 0-м, верно?

А выводит:

Thread 0 started
Thread 0 counts 0
Thread 1 started
Thread 2 started
Thread 2 counts 0
Thread 1 counts 0
Thread 2 counts 1
Thread 1 counts 1
Thread 1 counts 2
Thread 2 counts 2
Thread 1 counts 3
Thread 2 counts 3
Thread 1 counts 4
Thread 2 counts 4
Thread 0 counts 1
Thread 0 counts 2
Thread 0 counts 3
Thread 0 counts 4

Окей, видно что 0-й поток в аутсайдерах, как и должно быть, но ведь 2-й поток должен быть на много приоритетнее чем 1-й, 
а они как на равных.. 1-й даже на 2-й итерации начал обгонять 2-1.  С таким раскладом приоритетность вообще теряет свой смысл.. Может я что-то не так делаю?

Автор: jk1 9.7.2010, 13:37
Дело в том, что выставление приоритетов само по себе ничего не гарантирует
Цитата

Rule of thumb: At any given time, the highest priority thread is running. However, this is not guaranteed. The thread scheduler may choose to run a lower priority thread to avoid starvation. For this reason, use priority only to affect scheduling policy for efficiency purposes. Do not rely on thread priority for algorithm correctness.

http://www.javamex.com/tutorials/threads/priority.shtml можно почитать подробнее о том, как это на самом деле работает.

Автор: lazycat 9.7.2010, 16:27
Цитата(soulcub @  9.7.2010,  13:08 Найти цитируемый пост)
тут же должно быть отчётливое доминирование 2-го над 1-м, и их обоих над 0-м, верно?

Не факт.  Это зависит от множества причин, в частности от используемой операционной системы. Дело в том, что для поддержки потоков JVM напрямую использует соответствующие средства ОСю
Например, в Java определено 10 приоритетов для потоков, а в Windows - только 7. В результате 10 приоритетов отображаются в 7.
Более того, в какой-то из версий Linux (не помно в какой) приоритеты вообще не поддерживаются. Результат не трудно предсказать, не так ли?
Одним словом, приоритеты - это только "благие намерения". Полагаться на них - это значит создавать все условия для самых мерзких ошибок - тех, которые проявляются лишь изредка и надолго исчезают.
Если Вам важен порядок запуска потоков, используйте средства синхронизации,  семафоры, барьеры, если они не позволяют сделать то, что Вам надо, устанавливайте и проверяйте флаги самостоятельно.

Автор: soulcub 9.7.2010, 19:28
Та почему-то на собеседовании на работу очень спрашивали именно про приоритетность потоков) Может про то, что не следует на них полагаться он ии хотели услышать, ну да ладно) Спасибо большое за ответы, совершенствуем знания =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)