• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Kolejkowanie w Java - problem fabryki

Object Storage Arubacloud
0 głosów
134 wizyt
pytanie zadane 20 maja 2023 w Java przez Danny26 Nowicjusz (220 p.)

Cześć,

Nie wiem do końca jak mam się zabrać za zadanie w którym:

Cukiernik produkuje ciastka i kładzie je na taśmie produkcyjnej - cukierników jest wielu.

Pakowacz bierze dwa ciastka z taśmy produkcyjnej, zawija je w sreberko po czym  zawinięte dwa ciastka umieszcza je na drugiej taśmie produkcyjnej (zawinięte dwa ciastka traktowane są jako jeden produkt) - pakowaczy jest wiele

Reszta zadania jest nieistotna, nie wiem dokładnie jak zabrać się do tego elementu w którym gotowe już 2 ciastka pakowacz łączy jako jedno opakowanie, nadaje mu nowy numer seryjny i odkłada na drugą taśmę.

Poniżej przedstawiam klasę samego Pakowacza, nie wiem czy przyda się tutaj też klasa Piekarza i Main, jeżeli będzie to niezbędne do naprowadzenia mnie w którą stronę mam iść to oczywiście podam to poniżej w komentarzu.

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class Pakowacz extends Thread{
    private final BlockingQueue<Integer> kolejka;
    public Pakowacz(BlockingQueue<Integer> kolejka){
        this.kolejka = kolejka;
    }

    @Override
    public void run() {
        String nazwa = getName();
        try{
            while(true){
                final BlockingQueue<Integer> kolejka2 = null;
                int ciastko = kolejka.take();
                
                System.out.println(nazwa+" Pakuje w sreberko "+ ciastko);
                
                    System.out.println(nazwa + " Odlozyl na nowa tasma: ");
                
            }
        }catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

Z góry dziękuję za pomoc. :)

1 odpowiedź

+2 głosów
odpowiedź 20 maja 2023 przez Wiciorny Ekspert (269,590 p.)
Jedyne co mi przychodzi do głowy to aby traktować paczkę jako Touple: typu obiektowego
https://docs.oracle.com/middleware/11119/jdev/api-reference-esdk/oracle/javatools/util/Tuple.html

-cukierników jest wielu:
Więc to bym traktował jako "wątki", to jest klasyczne zadanie na wątki i np wykorzystanie ExecutorService. Każdy jeden wątek działający to "worker".
Pakowacz jest jeden?
Jeśli tak to mamy tutaj problem z blokującym mechanizmem gdzie  "działanie" jednego z wątków pakowacza, powinno być synchronizowane, tak aby wszystkie inne wątki czekał na zwolnienie (coś kurcze mi tu śmierdzi problemem SEMAFORA) i jego wykorzystaniem praktycznym.

Prodkut, box na ciastka możesz traktować jako TOUPLE, albo jako mape: która zawiera klucz- będący czymś co odróżnia od siebie każy box ciastek (numer seryjny), a  ciastkami będzie zbiór np. powiedzmy że mimo wszystko każde ciastko nie jest tym samym obiektem mimo, że jednak jest robione z tego samego.

Jak łączyć ciastka,  więc ustawić jakąs funkcja działającą co "Dwa elementy" i dodawać dwa elementy do zbioru, kiedy zbiór będzie miał 2 elementy, koniec generujemy NR SERYJNY wsadzamy jako klucz do mapy, i pod tym kluczem wsadzasz ten box ciastek, i powtarzasz to dla kolejnych ciastek.

Tyle na daną chwile mi przychodzi do głowy, jesli rozumiem twój problem. Dawaj znać jak coś, rozwinę myśl.
1
komentarz 20 maja 2023 przez Danny26 Nowicjusz (220 p.)

Cześć,

Dziękuję za odpowiedź, w trakcie czekania na odpisanie, pomyślałem jak mogę to zrobić. 

Dodałem po prostu drugą kolejkę którą nazwałem linia2 a z linii pierwszej użyłem podwójnie metody take().

Poniżej dla potomnych zostawiam część mojego kodu, tak jak ja rozwiązałem ten problem. :)

 

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class Pakowacz extends Thread{
    private BlockingQueue<Integer> linia1;
    private BlockingQueue<Integer> linia2;
    private static AtomicInteger seryjny2 = new AtomicInteger(1);
    public Pakowacz(BlockingQueue<Integer> kolejka, BlockingQueue<Integer> linia2){
        this.linia2 = linia2;
        this.linia1 = kolejka;
    }

    @Override
    public void run() {
        String nazwa = getName();
        int dane;
        try{
            while(true){
                dane = seryjny2.getAndIncrement();
                int ciastko = linia1.take();
                System.out.println(nazwa+" Pakuje w sreberko "+ ciastko);
                int ciastko2 =linia1.take();
                System.out.println(nazwa+ "Pakuje w sreberko "+ ciastko2);
                linia2.put(dane);
                System.out.println(nazwa + " Odlozyl na nowa tasma: " + dane);
            }
        }catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

PS. długo myślałem dlaczego AtomicInteger pomimo tego, że jest Atomic dopuszcza cały czas te same numery seryjne, rozwiązaniem problemu jest zrobienie Atomica statycznym. wink

komentarz 20 maja 2023 przez Wiciorny Ekspert (269,590 p.)

Tzn AtomicInteger to po prostu Integer z gwarancją w kwesti odczytu przy pracy między wielomawątkami.
Inaczej mówiąc: Zadaniem tej klasy jest zapewnienie bezpiecznego dostępu do wartości całkowitej w kontekście wielowątkowości, że odczyt zawsze gwarantuje 
Dzięki temu możesz wykonywać operacje inkrementacji, dekrementacji, odczytu i innych na tej wartości w sposób bezpieczny, nawet jeśli wiele wątków jednocześnie próbuje korzystać z danej zmiennej która jest Atomowa, zawsze otrzymasz najbardziej aktualny wynik.
(eliminując problemy związane z wyścigami (race conditions) i zapewniając spójność wyników).

Statyczny rozwiązuje sprawę tylko i wyłącznie dlatego, że zmienna nie przynależy do pojedyncze obiektu, a jest częścią szablonu klasy, wspólną dla wszystkich obiektów/instancji tej klasy  

Dlaczego wcześniej nie działało, dlatego że tak naprawdę 
Każdy twój obiekt na nowo tworzy 
 

 seryjny2 = new AtomicInteger(1);

jest to część obiektu- wątku, więc każdy wątek tworzy Ci własny egzemplarz i własny numer seryjny równy 1. 
Co to oznacza?

A no to, że wartości AtomicInteger nie będą współdzielone między wątkami. Każdy wątek będzie operował na swojej instancji AtomicInteger, niezależnie od innych wątków.

komentarz 26 maja 2023 przez Danny26 Nowicjusz (220 p.)
Hej,

W takim razie jak to zrobić, żeby nadać jeden numer seryjny, np. jakbym chciał go nadać odrazu na początku produkcji i tak, żeby dojechał aż do końca, ale w każdej klasie, żeby został wyświetlony?

Nie ma tego w zadaniu, ale na pewno przyda mi się to w przyszłości do innych zadań.

Oczywiście, nie chodzi mi tutaj o podanie gotowego kodu, tylko bardziej nakierowanie tak jak napisałeś to teraz.

Dziękuję za odpowiedź!

Podobne pytania

0 głosów
1 odpowiedź 159 wizyt
pytanie zadane 8 lutego 2021 w PHP przez XiverKi Bywalec (2,050 p.)
0 głosów
2 odpowiedzi 393 wizyt
0 głosów
1 odpowiedź 181 wizyt
pytanie zadane 2 listopada 2022 w Java przez Digi26 Nowicjusz (120 p.)

92,539 zapytań

141,382 odpowiedzi

319,480 komentarzy

61,928 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...