Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.01.07;
Скачать: [xml.tar.bz2];

Вниз

Помогите студиозусу...   Найти похожие ветки 

 
Павел Калугин ©   (2006-12-17 11:49) [0]

Задача
Очередь ограниченного размера
Поток, который поставляет значения в очередь.
Поток, который выбирает значения из очереди.
--------------------------------------------
пытаюсь реализовать
очередь - LIFO
метод push - если в очереди последний элемент нулевой то помещаем элемент в начало
метод pop - если в очереди первый элемент не нулевой выбираем его

Пожалуйста помогите найти ошибки, и разобратся почему написано у меня неправильно

Получился следующий код на Java

package laba;
class Queue { // Очередь. Стек.
   private int st[];
   private int st_len;
   private boolean stop_flag;    
   
   public Queue(int len)  {
       st = new int[len];
       st_len = len;
       stop_flag=false;
       System.out.println("Создан массив из " + st_len + " элемнентов");
       for(int i=0;i<st_len;i++){
           System.out.print(st[i]+"; ");
       }
       System.out.println("\n");
   }
   synchronized public void push(int in_value){
       if (st[st_len-1]!=0) {// ждем свободного места в очереди
           try {
               wait();
           } catch (InterruptedException ex) {
               ex.printStackTrace();
           }
           
       }

       for(int i=st_len-1;i>0;i--){
           st[i]=st[i-1];
       }
       st[0]=in_value;
       System.out.println("Записано "+in_value);
       
       notify();        
   }
   synchronized public int pop(){
       int out_value;
       if (st[0]==0) {//я так понимаю, ждем изменения значения ST[0]? то есть появления в очереди элементов
           try {
               wait();
           } catch (InterruptedException ex) {
               ex.printStackTrace();
           }
       }

       out_value= st[0];
       int i;
       
       for(i=0;i<st_len-1;i++){
           if (st[i+1]==0) break;
           st[i]=st[i+1];
       }
       st[i]=0;

       notify();
       return out_value;
   }
   
   synchronized public void SetStop(boolean in_v){
       stop_flag=in_v;
   }
   synchronized public boolean GetStop(){
       return stop_flag;
   }
   synchronized public boolean GetStopRead(){
       return stop_flag & st[0]==0;
   }
}
/******************************************************************************** ********/
class Producer implements Runnable{// поток производитель значений
   Queue q;
   boolean is_last;
   Thread t;
   public Producer(Queue in_q, boolean cond,String name){
       q=in_q;
       is_last=cond;
       t=new Thread(this,name);
       t.start();
   }
   public void run(){
       for(int i=1;i<=5;i++){
           if (q.GetStop()){
               System.out.println("Получено разрешение, уничтожен поток "+t.getName());
               break;
           }
           System.out.println("Сформировано "+i+" Потоком "+t.getName());
           q.push(i);
       }
       if (is_last) q.SetStop(true);//Выставляем флаг прекращать работу
   }
}
/****************************************************************/
class Reader implements Runnable{// поток получатель
   Queue q;
   Thread t;
   public Reader(Queue in_q,String name){
       q=in_q;
       t=new Thread(this,name);
       t.start();
   }
   public void run(){
       while(true){
           if (q.GetStopRead()){
               System.out.println("Получено разрешение  читать нечего, уничтожен поток "+t.getName());
               break;
           }
          int i;
          i = q.pop();
         System.out.println("Получено "+i+" Потоком "+t.getName());
         
       }
       
   }
}
/********************************/
public class Main {
   
   public Main() {
       
   }
   public static void main(String[] args) {
       Queue q=new Queue(8);
       for(int i=0;i<10;i++){
           new Producer(q,false,"Producer "+i);
       }
       for(int i=0;i<10;i++){
           new Reader(q,"Reader "+i);
       }
       new Producer(q,true,"Producer "+100);//последний поток писатель. по его завержении все остальные потоки начинают завершать раюоту

   }
   
}


 
Павел Калугин ©   (2006-12-17 11:56) [1]

насколько я понимаю, в методе push следующий фрагмент
if (st[0]==0) {
          try {
              wait();
          } catch (InterruptedException ex) {
              ex.printStackTrace();
          }
      }

не должен позволить выбирать нули.
Но в результатах проскакивает
Получено 0 Потоком Reader 3
Получено 0 Потоком Reader 9
Получено 0 Потоком Reader 0

а почему - не понимаю...


 
Павел Калугин ©   (2006-12-17 11:57) [2]

> [1] Павел Калугин ©   (17.12.06 11:56)
> push

в методе pop, простите


 
Павел Калугин ©   (2006-12-18 10:26) [3]

Эх :( надо былдо писать что нибудь вида "дайте код".


 
jack128 ©   (2006-12-18 11:28) [4]

В что функция Wait() делает то???  В одном контексте ты говоришь, что она "ждет свободного места в очереди", а в дргуом случае она у тя ждет "появления в очереди элементов" .  А как она вообще догадывает, что ей нужно ждать???


 
Павел Калугин ©   (2006-12-18 12:12) [5]

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


 
Павел Калугин ©   (2006-12-18 13:00) [6]

а если метод pop() изменить следующим образом
   synchronized public int pop(Thread t){
       int out_value;
//        if (st[0]==0) {//я так понимаю, ждем изменения значения ST[0]? то есть появления в очереди элементов
//            try {
//                wait();
//            } catch (InterruptedException ex) {
//                ex.printStackTrace();
//            }
//        }
       while (st[0]==0){
           try {
                t.sleep(100);
                if (stop_flag) return -1;
          } catch (InterruptedException ex) {
               ex.printStackTrace();
          }

то на очередном шаге чтчтения просто все встает раком...            
       }


 
Павел Калугин ©   (2006-12-18 14:33) [7]

во блин. нашел...
Note: Always invoke wait inside a loop that tests for the condition being waited for. Don"t assume that the interrupt was for the particular condition you were waiting for, or that the condition is still true.
Всем спасибо за помощь...



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2007.01.07;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.02 c
15-1166347457
Alex_ey
2006-12-17 12:24
2007.01.07
outlook


15-1166193936
ProgRAMmer Dimonych
2006-12-15 17:45
2007.01.07
Если мнишь себя поэтом - погляди на ветку эту


2-1166376380
Ricks
2006-12-17 20:26
2007.01.07
Регистрация файла


4-1154781641
fufel
2006-08-05 16:40
2007.01.07
drag i drop | delphi i iexplorer


15-1166368619
tesseract
2006-12-17 18:16
2007.01.07
1-Wire и другие средства автоматизации дома





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский