🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.java
11 messages
11 total messages Started by pamysz Thu, 17 Nov 2011 16:01
Dodawanie do kolejki SynchronousQueue
#153141
Author: pamysz
Date: Thu, 17 Nov 2011 16:01
70 lines
3604 bytes
W momencie wykonywania instrukcji : kolejkaSQ.put(obiekt) program
zawiesza się.
Dla kolejki LinkedBlockingQueue wszystko jest ok.
Kiedyś (przed reinstalacją NB i JDK) wszystko działało.
Teraz jest NetBeans 7.0.1, Java 1.6.0_24.
Poniżej kod klasy:
package testkolejki;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TestKolejki {

    class OnOf {
        boolean on;
        public OnOf(boolean on)
        {
            this.on = on;
        }
    }
    public static void main(String[] args)
    {
        LinkedBlockingQueue<OnOf> kolejkaLQ = new
LinkedBlockingQueue();
        SynchronousQueue<OnOf> kolejkaSQ = new SynchronousQueue();
        TestKolejki tk = new TestKolejki();
        OnOf o1 = tk.new OnOf(true);
        OnOf o2 = tk.new OnOf(false);
        OnOf oN = tk.new OnOf(false);
        //----------------------------------------------------------------------
        System.out.println("1. Kolejka LQ pusta = " +
kolejkaLQ.isEmpty());
        System.out.println("1. Kolejka SQ pusta = " +
kolejkaSQ.isEmpty());
        System.out.println("Adres ok1 = " + o1.hashCode() + ",  " +
o1.toString());
        System.out.println("Adres ok2 = " + o2.hashCode() + ",  " +
o2.toString());
        System.out.println("---------- Koniec deklaracji
-----------------------------------------");
        try
        {
            kolejkaLQ.put(o2);
            System.out.println("2. Kolejka LQ pusta = " +
kolejkaLQ.isEmpty());
            kolejkaSQ.put(o1);// tutaj program się wiesza
            System.out.println("2. Kolejka SQ pusta = " +
kolejkaSQ.isEmpty());
            System.out.println("---------- Koniec dodawania do kolejki
-----------------------------------------");
            oN = kolejkaLQ.take();

        } catch (InterruptedException ex) {
            System.out.println("Błąd !!!!!!!!!!!!!!!!!");
 
Logger.getLogger(TestKolejki.class.getName()).log(Level.SEVERE, null,
ex);
        }
        System.out.println("3. Kolejka LQ pusta = " +
kolejkaLQ.isEmpty() + ",  okN: " + oN.toString());
        System.out.println("3. Kolejka SQ pusta = " +
kolejkaSQ.isEmpty());
        System.out.println("-------- Koniec programu
-------------------------------------------");
        //----------------------------------------------------------------------
    }
}
Z góry dziękuję za pomoc.
Re: Dodawanie do kolejki SynchronousQueue
#153142
Author: nullpointer
Date: Thu, 17 Nov 2011 16:33
7 lines
1093 bytes
Pierwsze zdanie w javadocu klasy SynchronousQueue (wytłuszczenie moje):

A blocking queue in which *each put must wait for a take, and vice versa*.

Jaki konkretnie jest Twój problem? ;-)
-- 
npe
Re: Dodawanie do kolejki SynchronousQueue
#153143
Author: pamysz
Date: Thu, 17 Nov 2011 17:00
18 lines
1935 bytes
On Nov 17, 5:33 pm, nullpointer <i....@nie.dojdzie.pl> wrote:
> Pierwsze zdanie w javadocu klasy SynchronousQueue (wytłuszczenie moje):
>
> A blocking queue in which *each put must wait for a take, and vice versa*.
>
> Jaki konkretnie jest Twój problem? ;-)
> --
> npe

Jak uruchamiam ten programik w NB, to po:
System.out.println("2. Kolejka LQ pusta = " +  kolejkaLQ.isEmpty());
program czeka jakby na zwolnienie kolejki (jednoelementowa jest), ale
wcześniej do niej nic nie dodawałem:
a zachowuje się jakby już nie była pusta.
Żadnego komunikatu, nic.
Jak wykomentuję linię:
kolejkaSQ.put(o1);// tutaj program się wiesza
to program wykonuje się dalej.
Re: Dodawanie do kolejki SynchronousQueue
#153144
Author: nullpointer
Date: Thu, 17 Nov 2011 17:19
12 lines
1428 bytes
No to jeszcze raz, jak krowie na rowie.

Każy *put* wywołany na SynchronousQueue zablokuje się do momentu, aż 
ktoś (czytaj: inny wątek) wywoła *take* i odbierze element. To jest 
jasno opisane w javadoc, którego nie przeczytałeś, albo nie rozumiesz 
działania kolejek blokujących w ogóle i nie wpadłeś na to aby stworzyć 
dwa wątki (poczytaj o wzorcu Producer/Consumer).

P.S. NetBeans nie ma nic do tego.

-- 
npe
Re: Dodawanie do kolejki SynchronousQueue
#153145
Author: pamysz
Date: Thu, 17 Nov 2011 17:58
46 lines
3467 bytes
On Nov 17, 6:19 pm, nullpointer <i....@nie.dojdzie.pl> wrote:
> No to jeszcze raz, jak krowie na rowie.
>
> Ka y *put* wywo any na SynchronousQueue zablokuje si do momentu, a
> kto (czytaj: inny w tek) wywo a *take* i odbierze element. To jest
> jasno opisane w javadoc, kt rego nie przeczyta e , albo nie rozumiesz
> dzia ania kolejek blokuj cych w og le i nie wpad e na to aby stworzy
> dwa w tki (poczytaj o wzorcu Producer/Consumer).
>
> P.S. NetBeans nie ma nic do tego.
>
> --
> npe

Przeczytałem, ale chyba bez prawidłowego zrozumienia ;)
W programie (nie w tym) wątek dodaje obiekt do kolejki, a 2 wątek go
odczytuje.
Tutaj tylko dla testów stworzyłem klase jw. bo program zaczął się
wieszać w miejscu dodawania do kolejki SynchronousQueue.
Program skompilowany parę miesięcy temu działa prawidłowo.
Teraz dodawałem nowy wątek robiący to samo i program zaczął się
wieszać w momencie dodawania do kolejki w wątku który działał.
Moim zdaniem wątek powinien dodać do pustej kolejki i nie czekać na
odebranie z kolejki przez inny wątek tylko dalej się wykonywać.
Wyżej dla testów tworzę kolejkę, wyświetlam, że jest pusta i zapisuję
do kolejki 1 obiekt.
Chcę, żeby wypisał się komunikat, że zapisało do kolejki, ale program
czeka.
Według ciebie czeka, aż inny wątek zwolni kolejkę? Po co. Jego to nie
powinno interesować.
Wątek nie może wykonać put, gdy kolejka jest pełna, a take gdy jest
pusta - wtedy czeka.
Dlaczego ten sam wątek nie może zapisać do kolejki wyświetlić
komunikat i potem tego odczytać?
Byle najpierw zapisywał do pustej potem zwalniał i tak w kółko
Dla LinkedBlockingQueue robi to bez problemu, nie czeka na zwolnienie
tylko wyświetla komunikat.

kolejkaSQ.put(o1);// zapisanie do kolejki
System.out.println("zapisano"); // wyświetlenie komunikatu "zapisano".
Nie wyświetla "zapisano" dla SynchronousQueue.

kolejkaSQ.put(o1);// zapisanie do kolejki
o1 = kolejkaSQ.take();// pobranie z kolejki
System.out.println("zapisano");
też nie wyświetla "zapisano" tylko czeka w linii  put.
Re: Dodawanie do kolejki SynchronousQueue
#153147
Author: pamysz
Date: Thu, 17 Nov 2011 18:04
2 lines
1542 bytes
Czyli krótko mówiąc ten sam wątek nie może wykonać metody put, a potem
take na tej samej kolejce SynchronousQueue ?
Re: Dodawanie do kolejki SynchronousQueue
#153146
Author: nullpointer
Date: Thu, 17 Nov 2011 19:04
26 lines
1785 bytes
W dniu 2011-11-17 18:58, pamysz pisze:
> Moim zdaniem wątek powinien dodać do pustej kolejki i nie czekać na
> odebranie z kolejki przez inny wątek tylko dalej się wykonywać.

Tak działa LinkedBlockingQueue.

> Według ciebie czeka, aż inny wątek zwolni kolejkę? Po co. Jego to nie
> powinno interesować.

Tak działa SynchronousQueue.

> Wątek nie może wykonać put, gdy kolejka jest pełna, a take gdy jest
> pusta - wtedy czeka.

Tak działa LinkedBlockingQueue.

> Dlaczego ten sam wątek nie może zapisać do kolejki wyświetlić
> komunikat i potem tego odczytać?

Tak działa SynchronousQueue.


Pytanie: Po co w ogóle używasz SynchronousQueue?

-- 
npe
Re: Dodawanie do kolejki SynchronousQueue
#153148
Author: nullpointer
Date: Thu, 17 Nov 2011 19:12
23 lines
2049 bytes
W dniu 2011-11-17 19:04, pamysz pisze:
> Czyli krótko mówiąc ten sam wątek nie może wykonać metody put, a potem
> take na tej samej kolejce SynchronousQueue ?

No nareszcie... *

*) Oczywiście to jest tylko pół prawdy. Wątek może wykonać put, a 
następnie take na tej samej SQ, pod warunkiem, że po tym put, jakiś 
drugi wątek wywoła take, a następnie put na tej kolejce. Wtedy take 
wykonany w wątku pierwszym pobierze ci obiekt "zaputowany" w wątku drugim.

Zrobić tego bez dodatkowego, drugiego wątku się nie da** bo wywołanie 
put w wątku pierwszym zablokuje go do momentu wywołania take w wątku drugim.

**) Oczywiście zamiast wywołania take w wątku drugim, można na wątku 
pierwszym wywołać interrupt() i wtedy put zakończy się wyjątkiem 
InterruptedException, który możesz obsłużyć i "jechać dalej" w wątku 
pierwszym z czym tam sobie zaimplementujesz.

Zamotałem Ci wystarczająco? ;)

-- 
npe
Re: Dodawanie do kolejki SynchronousQueue
#153149
Author: pamysz
Date: Thu, 17 Nov 2011 19:40
5 lines
1753 bytes
Dzięki, czyli jeśli zależy mi, aby kolejka była 1 elementowa muszę
zastosować bodajże ArrayBlockingQueue[1] ? by nie blokować wątku po
put?
Najgorsze, że program działał "poprawnie", ale nie według moich
zamierzeń.
Re: Dodawanie do kolejki SynchronousQueue
#153150
Author: nullpointer
Date: Thu, 17 Nov 2011 20:56
14 lines
1513 bytes
W dniu 2011-11-17 20:40, pamysz pisze:
> Dzięki, czyli jeśli zależy mi, aby kolejka była 1 elementowa muszę
> zastosować bodajże ArrayBlockingQueue[1] ? by nie blokować wątku po
> put?

Tak

> Najgorsze, że program działał "poprawnie", ale nie według moich
> zamierzeń.

Bo nie czytasz dokumentacji ;)

-- 
npe
Re: Dodawanie do kolejki SynchronousQueue
#153151
Author: pamysz
Date: Thu, 17 Nov 2011 21:04
20 lines
2046 bytes
On Nov 17, 9:56 pm, nullpointer <i....@nie.dojdzie.pl> wrote:
> W dniu 2011-11-17 20:40, pamysz pisze:
>
> > Dzięki, czyli jeśli zależy mi, aby kolejka była 1 elementowa muszę
> > zastosować bodajże ArrayBlockingQueue[1] ? by nie blokować wątku po
> > put?
>
> Tak
>
> > Najgorsze, że program działał "poprawnie", ale nie według moich
> > zamierzeń.
>
> Bo nie czytasz dokumentacji ;)
>
> --
> npe

Czytałem, ale najwyraźniej bez zrozumienia. Wtórny analfabetyzm, czy
co :)
W każdym razie jeszcze raz dzięki.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads