Re[8]: пулл обектов. как оно на самом деле....
От: Shabi  
Дата: 13.08.07 07:31
Оценка:
Здравствуйте, mikkri, Вы писали:

еще раз....
тут совершенно короткий отрывок, поэтому прочтите до конца, это не сложно.

увидив в моем коде вот это


public static void main(String[] args)
    {
        new Thread()
        {
            public void run()
            {
                test1();
            }
        }.start();
        new Thread()
        {
            public void run()
            {
                test1();
            }
        }.start();
        new Thread()
        {
            public void run()
            {
                test1();
            }
        }.start();
        new Thread()
        {
            public void run()
            {
                test1();
            }
        }.start();

        ///===================================================

        new Thread()
        {
            public void run()
            {
                test2();
            }
        }.start();
        new Thread()
        {
            public void run()
            {
                test2();
            }
        }.start();
        new Thread()
        {
            public void run()
            {
                test2();
            }
        }.start();
        new Thread()
        {
            public void run()
            {
                test2();
            }
        }.start();
    }



цитирую — denis.zhdanov пишет

Также тест неправильный еще и из-за того, что потоки, выполняющие test1() стартуют раньше потоков, выполняющих test2() ==> вторая группа работает в режиме более жесткой конкуренции за системные ресурсы.


на что я отвечаю

это замечание Вас дескридитирует, как профессионала. Нет там понятия раньше позже.


вы со мной согласны?


на что я получаю ответ

Если вы хотите, чтобы у вас не было понятия раньше позже -- используйте например, барьеры, чтобы все потоки начали выполнение одновременно (ну, или почти одновременно ). А то один поток может вообще завершится, пока другой не начнется.


я так и не понял. с кем автор разговаривал. кто чего я хотел? я? ничего я не хотел вообще.
и тут Вы продолжаете...в том же духе.

M>Речь о том, что когда вы последовательно запускаете потоки, то они стартуют не одновременно, как нужно для теста, а последовательно. И из-за задержек, связанных с созданием нового потока, времена запуска потоков будут сильно разниться.


M>Чтобы ситуацию приблизить к жизненной нужно использовать барьер, т.е. механизм, который не даст вашим потокам исполнять "бизнес-логику" до того, как все потоки дойдут до барьера. В такой ситуации потоки начнут исполнять "бизнес-логику" почти одновременно — с минимально возможной задержкой.


кто Вам сказал что для теста нужно чтобы потоки стартовали одновременно? и откуда информация про минимально возможную задержку?

я в недоумении. там все отданно на откуп шедулерру потоков. барьер вам только гарантирует только понятие "не раньше чем" и все.
Re[5]: [от модератора]
От: Blazkowicz Россия  
Дата: 13.08.07 10:58
Оценка:
Здравствуйте, Shabi, Вы писали:

S>это замечание Вас дескридитирует, как профессионала. Нет там понятия раньше позже.


Прошу обратить Ваше внимание, что процитированный пассаж является грубым нарушением Обязательных правил сайта. Подобное поведение в дальнейшем может повлечь за собой ограничения ваших свобод на rsdn.ru
Re[9]: пулл обектов. как оно на самом деле....
От: Blazkowicz Россия  
Дата: 13.08.07 11:33
Оценка:
Здравствуйте, Shabi, Вы писали:

S> я в недоумении. там все отданно на откуп шедулерру потоков. барьер вам только гарантирует только понятие "не раньше чем" и все.


Правильно, что в свою очередь очень здорово сокращает время между реальными запусками методов.
Может это... зачем трепаться по пусту. Запустим, да проверим. Уже на 10 потоках разница хорошо видна не вооруженным глазом.

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.ArrayList;
import java.util.List;

/**
 * This class represents...
 */
public class Test
{
    private static final int PARTIES = 10;

    private static void test(long start)
    {
        System.out.println(Thread.currentThread().getName() + "  " + (System.nanoTime() - start));
    }

    public static void main(String[] args) throws InterruptedException
    {
//        test1();
//        test2();
        test3();
    }

    private static void test2() throws InterruptedException
    {
        final CyclicBarrier barrier = new CyclicBarrier(PARTIES);
        List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
        final long start = System.nanoTime();
        for (int i = 0; i < PARTIES; i++)
        tasks.add(new Callable<Object>()
        {
            public Object call() throws Exception
            {
                barrier.await();
                test(start);
                return null;
            }
        });
        Executors.newScheduledThreadPool(tasks.size()).invokeAll(tasks);
    }


    private static void test1()
    {
        final long start = System.nanoTime();
        for (int i = 0; i < PARTIES; i++)
        {
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
        }
    }
    private static void test3()
    {
        final long start = System.nanoTime();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
            new Thread(){
                public void run()
                {
                    test(start);
                }
            }.start();
        }

}
Re[10]: пулл обектов. как оно на самом деле....
От: Shabi  
Дата: 14.08.07 05:42
Оценка:
Здравствуйте, Blazkowicz, Вы писали:


B>
B>import java.util.concurrent.CyclicBarrier;
B>import java.util.concurrent.Callable;
B>import java.util.concurrent.Executors;
B>import java.util.ArrayList;
B>import java.util.List;

B>/**
B> * This class represents...
B> */
B>public class Test
B>{
............

B>    private static void test2() throws InterruptedException
B>    {
B>        final CyclicBarrier barrier = new CyclicBarrier(PARTIES);
B>        List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
B>        final long start = System.nanoTime();
B>        for (int i = 0; i < PARTIES; i++)
B>        tasks.add(new Callable<Object>()
B>        {
B>            public Object call() throws Exception
B>            {
B>                barrier.await();
B>                test(start);
B>                return null;
B>            }
B>        });
B>        Executors.newScheduledThreadPool(tasks.size()).invokeAll(tasks);
B>    }

B>            new Thread(){
B>                public void run()
B>                {
B>                    test(start);
B>                }
B>            }.start();
B>        }

B>}
B>


Эх, хорошо.... пока такой код будет обнаруживаться в проектах...я без работы не останусь.
Все понимаю, новые JDK, новомодные патерны...но для чего так код усложнять-то...?
Возможно, что это дело вкуса...не буду спорить.

В моем исполнении все тоже самое будет выглядить так...


public class test2
{
    static long min_time = Long.MAX_VALUE, max_time = Long.MIN_VALUE;
    static String min_name = "", max_name = "";

    static final Object lock1 = new Object();

    static int threads_count = 10, current_count = 0;

    public static void test()
    {
        long t = System.nanoTime();

        synchronized (lock1)
        {
            if (min_time == Long.MAX_VALUE)
            {
                min_time = max_time = t;
                min_name = max_name = Thread.currentThread().getName();
            }
            else if (t < min_time)
            {
                min_time = t;
                min_name = Thread.currentThread().getName();
            }
            else
            {
                max_time = t;
                max_name = Thread.currentThread().getName();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException
    {
        for (int i = 0; i < threads_count; i++)
        {
            new Thread()
            {
                public void run()
                {
                    test();
                }
            }.start();
        }
        Thread.sleep(1000);
        print_result();

        for (int i = 0; i < threads_count; i++)
        {
            new Thread()
            {
                public void run()
                {
                    synchronized (lock1)
                    {
                        current_count++;
                        try
                        {
                            lock1.wait();
                        }
                        catch (InterruptedException e) {}
                    }

                    test();
                }
            }.start();
        }

        synchronized (lock1)
        {
            while (current_count < 10)
                lock1.wait(100);

            lock1.notifyAll();
        }

        Thread.sleep(1000);

        print_result();
    }

    private static void print_result()
    {
        System.out.println("Delta = " + (max_time - min_time));
        System.out.println("min_name = " + min_name);
        System.out.println("max_name = " + max_name);
        System.out.println();

        min_time = Long.MAX_VALUE;
        max_time = Long.MIN_VALUE;
        min_name = "";
        max_name = "";
    }
}


что имеем в результате....

я получаю примерно такие значения

Delta = 923022
min_name = Thread-9
max_name = Thread-0

Delta = 637511
min_name = Thread-19
max_name = Thread-10


Delta = 4899226
min_name = Thread-0
max_name = Thread-3

Delta = 634158
min_name = Thread-19
max_name = Thread-10


выводы

1) Как и предполагалось потоки стартуют так, как того захочет шедулер, порядок создания потоков и момент их реального старта никак не коррелирует. Нет понятие раньше позже, о чем я и писал.

2)действительно, при запуске всех потоков с синхронизацией через барьер разница между моментом старта первого и последнего стартующего меньше. То есть потоки стартуют более одновременно, чем без барьера.
НО! и это важно. Эту разницу можно заметить только на уровне наносекунд. Что для теста производительности пула и просто большинства тестов, совершенно не существенно. Там учет происходит с сотнях милисекунд.
Re[11]: пулл обектов. как оно на самом деле....
От: Blazkowicz Россия  
Дата: 14.08.07 08:56
Оценка:
Здравствуйте, Shabi, Вы писали:

S>Эх, хорошо.... пока такой код будет обнаруживаться в проектах...я без работы не останусь.

Работа в области обфускации исходного кода?

S>Все понимаю, новые JDK, новомодные патерны...но для чего так код усложнять-то...?

S>Возможно, что это дело вкуса...не буду спорить.
Возможно, что недостаток знания java.util.concurrent.* и пр. вызывает непонимаение? Я как-то не заметил что код приведенный ниже читается сильно лучше.

S>В моем исполнении все тоже самое будет выглядить так...

Все ясно. Консерватизм и велосипеды ещё инкто неотменял. Свое ведь всегда лучше.

S>выводы


S>1) Как и предполагалось потоки стартуют так, как того захочет шедулер, порядок создания потоков и момент их реального старта никак не коррелирует. Нет понятие раньше позже, о чем я и писал.

Но это все никак не связано с тем что время затрачиваемое на создание потока в Вашем примере влияет на результаты теста. На что сразу и было указано. А Вы сразу про "шедулер", "порядок"...

S>2)действительно, при запуске всех потоков с синхронизацией через барьер разница между моментом старта первого и последнего стартующего меньше. То есть потоки стартуют более одновременно, чем без барьера.

S>НО! и это важно. Эту разницу можно заметить только на уровне наносекунд. Что для теста производительности пула и просто большинства тестов, совершенно не существенно. Там учет происходит с сотнях милисекунд.
Ну, начинается. Нет никаких абстрактных сотен миллисекунд. Есть тесты, есть погрещность. Увеличь число потоков набежит и сотня и вообще сколько надо.
Re[12]: пулл обектов. как оно на самом деле....
От: Shabi  
Дата: 14.08.07 10:37
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

S>>В моем исполнении все тоже самое будет выглядить так...

B>Все ясно. Консерватизм и велосипеды ещё инкто неотменял. Свое ведь всегда лучше.

это опять таки дело вкуса....

S>>выводы


S>>1) Как и предполагалось потоки стартуют так, как того захочет шедулер, порядок создания потоков и момент их реального старта никак не коррелирует. Нет понятие раньше позже, о чем я и писал.

B>Но это все никак не связано с тем что время затрачиваемое на создание потока в Вашем примере влияет на результаты теста. На что сразу и было указано.

еще раз... Это мягко скажем...заблуждение, считать что первым запускаемый поток находится в превелигированном положении. Ибо далеко не факт, что он стартонет первым. Перечитайте там Денис именно об этом пишет.

Также тест неправильный еще и из-за того, что потоки, выполняющие test1() стартуют раньше потоков, выполняющих test2() ==> вторая группа работает в режиме более жесткой конкуренции за системные ресурсы.


ведь это очевидное заблуждение . Если совсем невериться, так переставте местами...сначала пусть вызываются test2() а потом test1() и получите такой же результат что и раньше...

и....ни на какие результаты влияния нет. ибо все подсчеты происходят внутри потока.

B>Ну, начинается. Нет никаких абстрактных сотен миллисекунд. Есть тесты, есть погрещность. Увеличь число потоков набежит и сотня и вообще сколько надо.


вот тут я согласен!!!! только совсем от реальности отрываться нестоит...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.