Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Синхронизация потоков 
V
    Опции темы
batex
Дата 21.10.2011, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 15.5.2010

Репутация: нет
Всего: нет



Возникла проблема с синхронизацией большого кол-во потоков с помощью функций wait(), notify(). Используется массив lock'ов. Код должен делать следующее: создает по параметру одинаковые потоки, которые уменьшают по очереди второй параметр. Потоки создаются, но в итоге программа виснет.
Код


public class NewThread
{
     
  public static int a;
  public static int b;
  public static Object[] sync;

    public static void main(String[] args) 
    {
     a = (Integer.parseInt(args[1]));
     b = (Integer.parseInt(args[0]));
     
     sync = new Object[b];
     for(int n = 0; n<b;n++)
         sync[n]=new Object();
     for(int i=0; i<b; i++)
        {
         if(i<b-1)
         {
             Thread t = new Thread(new WaitingThread(sync[i], sync[i+1]));
             t.start();
         }
         else
         {
             Thread t = new Thread(new WaitingThread(sync[i], sync[0]));
             t.start();
         }
             
           // System.out.println("1111");
            
        }
     
     synchronized(sync[0])
        {
           // System.out.println("Notify");
            sync[0].notify();         
     
        }
     
      
    }

    
    static class WaitingThread implements Runnable
    {

        static int nextId = 1;

        private Object sync;
        private int id;
        private Object sync1;
        
       
        public WaitingThread(Object sync,Object sync1) 
        {
            this.sync = sync;
            this.sync1 = sync1;
            id = nextId++;
        }

        public void run() 
        {        
         
            synchronized (sync) 
            {
             synchronized(sync1)
                {
                 sync1.notify(); 
             while(a > 0)
             {
                 
                   
                          
                    a--;
                    if (a < 0) break;
                    
                    System.out.println("Thread " +id +" "+ +a);
                    
                     
                      try 
                        {
                            sync.wait();
                        } catch (InterruptedException e) 
                        {
                         e.printStackTrace();
                        }
                    }
             } 
             
            }
            System.out.println("Threads " +id+ " finish");
        }
    }
}

PM MAIL   Вверх
LSD
Дата 21.10.2011, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Ctrl+Break выведет на консоль тред дамп, там можно посмотреть какой поток чем занят (только передай в конструктор Thread нормальное имя).

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


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
priam220
Дата 21.10.2011, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 4.6.2010

Репутация: 7
Всего: 8



в определенный момент они все у тебя засыпают, следовательно:
Код

//                        try {
//                            sync.wait();
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }


Вывод:
Thread 1 9
Thread 3 8
Thread 3 6
Thread 3 5
Thread 3 4
Thread 3 3
Thread 3 2
Thread 3 1
Thread 3 0
Threads 3 finish
Thread 1 7
Threads 1 finish
Threads 2 finish
Threads 5 finish
Threads 7 finish
Threads 4 finish
Threads 9 finish
Threads 6 finish
Threads 8 finish
Threads 10 finish


P.S. не ясно, что вы пытаетесь сделать wait/notify, причем применяя их к разным переменным. Но если дело в декременте, то лучше сделать так:
Код

            public void run() 
            {        
             while(a > 0){
              synchronized(a)                                  
                 {  
                        if (a < 0) break;
                        a--;
                        System.out.println("Thread " +id +" "+ +a);                        
                 } 
              try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                 
                }
                System.out.println("Threads " +id+ " finish");
            }


Это сообщение отредактировал(а) priam220 - 21.10.2011, 16:42
PM MAIL   Вверх
batex
Дата 21.10.2011, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 15.5.2010

Репутация: нет
Всего: нет



Цитата(LSD @ 21.10.2011,  15:56)
Ctrl+Break выведет на консоль тред дамп, там можно посмотреть какой поток чем занят (только передай в конструктор Thread нормальное имя).

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

Реализовать я хотел следующее: создать много одинаковых потоков, которые будут по очереди уменьшать параметр "а" на 1. У каждого потока есть свой sync для синхронизации.

Переменные для синхранизации разные - потому что я хотел сначала разбудить поток "n", потом уменьшить "а", потом разбудить следующий поток
PM MAIL   Вверх
priam220
Дата 21.10.2011, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 4.6.2010

Репутация: 7
Всего: 8



Пришлось немного задержаться на работе, но в конце-концов я понял, что нужно. Вот рабочий код:
Код

package ex;
public class Major
{
      public static int a;
      public static int b;
      public static Object[] sync;

        public static void main(String[] args) throws InterruptedException 
        {
         a = 50;
         b = 10;
         
         sync = new Object[b];
         for(int n = 0; n<b;n++)
             sync[n]=new Object();
         for(int i=0; i<b; i++)
            {
             if(i<b-1)
             {
                 Thread t = new Thread(new WaitingThread(sync[i], sync[i+1]));
                 t.start();
                 Thread.sleep(100);
             }
             else
             {
                 Thread t = new Thread(new WaitingThread(sync[i], sync[0]));
                 t.start();
                 Thread.sleep(100);
             }
                 
               // System.out.println("1111");
                
            }     
          
        }

        
        static class WaitingThread implements Runnable
        {

            static int nextId = 1;

            private Object sync;
            private int id;
            private Object sync1;
            boolean flag = false;
           
            public WaitingThread(Object sync,Object sync1) 
            {
                this.sync = sync;
                this.sync1 = sync1;
                id = nextId++;
            }

        public void run() {
            synchronized (sync) {
                
                while (a > 0) {
                    synchronized (sync1) {
                        sync1.notify();

                        a--;
                        if (a < 0) {
                            break;
                        }
                        System.out.println("Thread " + id + " " + +a);

                    }
                    try {
                            sync.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
                synchronized (sync1) {
                    sync1.notify();
                }
                
            }
            System.out.println("Threads " + id + " finish");
        }
    }
}


Код

Вывод:
Thread 1 49
Thread 2 48
Thread 3 47
Thread 4 46
Thread 5 45
Thread 6 44
Thread 7 43
Thread 8 42
Thread 9 41
Thread 10 40
Thread 1 39
Thread 2 38
Thread 3 37
Thread 4 36
Thread 5 35
Thread 6 34
Thread 7 33
Thread 8 32
Thread 9 31
Thread 10 30
Thread 1 29
Thread 2 28
Thread 3 27
Thread 4 26
Thread 5 25
Thread 6 24
Thread 7 23
Thread 8 22
Thread 9 21
Thread 10 20
Thread 1 19
Thread 2 18
Thread 3 17
Thread 4 16
Thread 5 15
Thread 6 14
Thread 7 13
Thread 8 12
Thread 9 11
Thread 10 10
Thread 1 9
Thread 2 8
Thread 3 7
Thread 4 6
Thread 5 5
Thread 6 4
Thread 7 3
Thread 8 2
Thread 9 1
Thread 10 0
Threads 2 finish
Threads 3 finish
Threads 1 finish
Threads 4 finish
Threads 5 finish
Threads 6 finish
Threads 7 finish
Threads 8 finish
Threads 9 finish
Threads 10 finish

Успехов!

Это сообщение отредактировал(а) priam220 - 21.10.2011, 23:21
PM MAIL   Вверх
batex
Дата 22.10.2011, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 15.5.2010

Репутация: нет
Всего: нет



Большое спасибо за помощь!
PM MAIL   Вверх
LSD
Дата 24.10.2011, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(batex @  21.10.2011,  18:36 Найти цитируемый пост)
Реализовать я хотел следующее: создать много одинаковых потоков, которые будут по очереди уменьшать параметр "а" на 1. У каждого потока есть свой sync для синхронизации.

Переменные для синхранизации разные - потому что я хотел сначала разбудить поток "n", потом уменьшить "а", потом разбудить следующий поток 

Уменьшать счетчик можно и без синхронизации.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
priam220
Дата 24.10.2011, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 4.6.2010

Репутация: 7
Всего: 8



Цитата(LSD @  24.10.2011,  10:28 Найти цитируемый пост)
Уменьшать счетчик можно и без синхронизации.

Можно использовать AtomicInteger. Но чем он лучше блока синхронизации?.. smile 
PM MAIL   Вверх
LSD
Дата 24.10.2011, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(priam220 @  24.10.2011,  14:52 Найти цитируемый пост)
Можно использовать AtomicInteger. Но чем он лучше блока синхронизации?

Быстрее и прозрачнее логика.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1023 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.