Форум: "Прочее";
Текущий архив: 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.48 MB
Время: 0.015 c