czwartek, 29 grudnia 2016

Wprowadzenie do programowania współbieżnego. Java util.concurent review... 1



    Przetwarzanie współbieżne (ang. concurrent computing) – przetwarzanie oparte na współistnieniu wielu wątków lub procesów, operujących na współdzielonych danych. Wątki uruchomione na tym samym procesorze są przełączane w krótkich przedziałach czasu, co sprawia wrażenie, że wykonują się równolegle. - tyle z Wikipedii ...


    W tym artykule nie będę się skupiać na teorii, pokażę kilka podstawowych klas i interfejsów jakie programiści mają do swojej dyspozycji aby móc tworzyć programy z użyciem wątków. Oczywiście w początkowych lekcjach skupimy się na podstawowych klockach z których możemy tworzyć nasze programy, nie mniej jednak jak później zobaczymy niektóre wykorzystywane przez nas klasy, mechanizmy będą tylko tłem dla wiedzy jaką chcę przekazać. Java oferuje nam dużo bardziej wyszukane mechanizmy pozwalające na obsługę wątków, ich wykonywania, odbierania od nich zadań. Dodatkowo Java 8 wprowadza nowy interfejs CompletableFuture umożliwiający nam na programowanie reaktywne, tworząc kod bardziej czytelnym i zrozumiałym. Nasze api nie zawsze musi być napisane w tradycyjny sposób, mam na myśli klient, czeka na zakończenie wywołanej przez niego metody (blokujące api), możemy mieć api, które będzie nam zwracać wynik, o którym zostaniemy powiadomieni, a wtedy możemy wykonać pewną akcję, akcja ta zostanie wywołana niezwłocznie po zakończeniu zadania, lecz bez blokowania wątku, z którego została wywołana nasza metoda. Z programowaniem współbieżnym wiąże się, także inne pojęcie synchronizacji, które jest kluczowym elementem jeśli nasze wątki operują na dzielonym zasobie, taki zasób utożsamiany będzie z pojęciem sekcji krytycznej... ale to wszystko później. Na początku skupmy się na podstawach.


    Przykłady, które będą umieszczone na stronie są pisane z użyciem wersji kompilatora Java 8. Sam wstęp ma pokazać pewien zarys jeśli chodzi o pewien koncept programowania współbieżnego oraz od strony technicznej jak wygląda to po stronie języka.



Spójrzmy na definicję interfejsu z pakietu java.util

    Co prawda interfejs ten nie należy do pakietu java.util.concurent, ale nie da się go pominąć chcąc przybliżyć możliwości jakie oferuje nam Java w kontekście programowania współbieżnego, lub po prostu nazwijmy to programowania z użyciem wątków.

Spójrzmy na definicję interfejsu z pakietu java.util


    Jak widać od wersji Javy 8 jest on opatrzony w adnotację @FunctionalInterface co oznacza, że jest to interfejs funkcyjny posiadający jedną abstrakcyjną metodę.

    Interfejs ten powinien być implementowany przez klasę, która ma reprezentować wykonanie pewnej operacji w wątku. Operację jaką chcemy wykonać, albo inaczej zadanie jest implementacją metody run.

    Od wersji Java 8 nie musimy jawnie deklarować klasy, która ma swoją nazwę, zaś możemy utworzyć implementację interfejsu za pomocą klasy anonimowej. Przejdźmy zatem do przykładu. Stworzymy w nim dwie implementacje metody run z interfejsu Runnable.


    W linijce 10 utworzyliśmy implementację interfejsu z użyciem klasy anonimowej, a w linijce 18 mamy bardziej eleganckie rozwiązanie, które oferuje nam Java 8. Użyliśmy tutaj wyrażenia lambda, inaczej mówiąc jest to funkcja anonimowa, która może przyjąć jakiś argument i go zwrócić lub nie.

    Interfejs Runnable definiuje nam funkcję taką w postaci metody run, która nie przyjmuje żadnego argumentu oraz nie zwraca żadnego rezultatu. Możemy to rozumieć na naszym przykładzie, że po operatorze -> przekazujemy ciało metody, w skrócie funkcję, która ma się wykonać w wątku.


    Samo zadeklarowanie klasy implementującej interfejs Runnable nie wystarcza aby nasz kod uruchomił się w oddzielnym wątku, potrzebujemy klasy, która będzie reprezentować ten wątek.
Klasa Thread z pakietu java.lang w jednym z konstruktorów przyjmuje właśnie obiekt Runnable, którego metoda run zostanie wywołana przy starcie nowego wątku.





    Wątek w ramach JVM zawsze musi należeć do pewnej grupy wątków. Grupa wątków reprezentowana przez klasę java.lang.ThreadGroup jest tworzona przy starcie maszyny wirtualnej o domyślnej nazwie "system". Grupy są zorganizowane w drzewo służą logicznemu podziałowi wątków.




    Poniżej widzimy, że w przypadku kiedy nie określimy w konstruktorze Thread, do jakiej grupy ma być przydzielony wątek zostanie wywołana metoda init z parametrem null. W linijce 371 pobierany jest aktualny wątek wykonujący się w ramach metody init, a w linijce 385 zostaje określona grupa do, której zostanie przydzielony wątek.






    Takie grupowanie daje pewną elastyczność oraz umożliwia wprowadzenie pewnych nazwijmy polityk bezpieczeństwa. Każdy wątek może należeć do jednej grupy, oraz możemy sprawdzić czy dany wątek próbuje utworzyć wątek z innej grupy.

    Poniżej mamy przykład programu wypisujący z bieżącego wątku wszystkie grupy w hierarchii drzewa.



    W prosty sposób możemy napisać program wypisujący nazwy wątków działających w maszynie wirtualnej Java.

    Metoda printAllThreadsCurrentlyRunningInJVM  na początku znajduje korzeń drzewa, a potem wywołuje metodę enumerate, która wypełnia podaną przez nas tablicę.





    W następnej lekcji skupimy się na klasie Thread, na jej metodach na stanach w jakich może znajdować się wątek.

   Api pakietu java.util.concurent w wersji 7 (nie znalazłem nigdzie 8, a nie chce mi się bawić w malarza uml)












środa, 14 września 2011

Windows 8 pre-beta



       Microsoft udostępnił wersję pre-beta (Windows Developer Preview) systemu operacyjnego Windows 8.Udostępniona wersja Windows 8 została określona przez Microsoft jako Windows Developer Preview. Oznacza to, że jest to wczesna wersja testowa, nie przeznaczona do codziennego użytkowania. Firma ostrzega, że system może działać niestabilnie. Użytkownicy mogą pobrać obraz płyty instalacyjnej (ISO) w jednym z trzech wariantów - wersja 64-bitowa, wersja 64-bitowa wraz z pakietem narzędzi programistycznych lub wersja 32-bitowa.
Microsoft podał minimalne wymagania sprzętowe systemu Windows 8 pre-beta. Do uruchomienia następcy Windows 7 wystarczy komputer z procesorem 1 GHz, 1 GB pamięci RAM (2 GB dla wersji 64-bit), układem graficznym zgodnym z DirectX 9 i 16 GB wolnego miejsca na dysku. W praktyce oznacza to, że Windows 8 pre-beta powinien bez problemu działać nawet na starszych, kilkuletnich maszynach. Firma ostrzega, że nie ma możliwości odinstalowania Windows 8 pre-beta - by przywrócić poprzedni system operacyjny, należy skorzystać z oryginalnego nośnika instalacyjnego lub utworzonej wcześniej kopii bezpieczeństwa. Oczywiście istnieje także możliwość wykonania czystej instalacji, która nie powinna naruszyć obecnego systemu operacyjnego.
Obraz płyty instalacyjnej Windows 8 pre-beta (Windows Developer Preview) można pobrać bezpośrednio ze strony Windows Dev Center.

      Oto film pokazujący instalację systemu na wirtualnej maszynie VirtualBox:




Tutaj zaś ciekawy film prezentujący szybkość ładowania się systemu na komputerze z tradycyjnym dyskiem mechanicznym.




Dla osób mających problem z instalacją Windows 8 na VirtualBox pre-beta polecam link :
http://www.sysprobs.com/guide-install-windows-8-virtualbox
źródło: dobreprogramy.pl

JAVA EE6 Programowanie aplikacji WWW KURS cz. 8 Wprowadzenie do JSP

     


      JSP - JavaServer Pages jest to technologia, która umożliwia zagnieżdżenie kodu Java w dokumentach HTML. Wcześniej skupialiśmy swoją uwagę na mechanizmie działania serwletów. Generowanie kodu HTML z wykorzystaniem metody println() obiektu PrintWriter. Takie podejście bardzo komplikuje kod i utrudnia korzystanie z narzędzi do tworzenia dokumentów HTML. Podział pracy między tworzeniem wizualnej strony, a tworzeniem logiki jest zachwiany. Odpowiedzią na powyższą wadę serwletów było opracowanie przez firmę Sun technologii JavaServer Pages.



      JSP pozwala nam na wstawianie do zwykłego kodu HTML konstrukcji w języku Java - co nie jest obecnie zalecane. Umieszczanie kodu Java w dokumencie HTML odbywa się z wykorzystaniem specjalnych znaczników.




      Takie umieszczenie konstrukcji językowych Java w dokumencie JSP nazywamy skryptami. Nie powinniśmy stosować takiego rozwiązania, ponieważ jak wiemy JSP zostało stworzone w celu uniknięcia niewygodnego generowania stron HTML z wykorzystaniem serwletów, a także do rozdzielenia mechanizmów aplikacji webowej czyli warstwy logiki aplikacji od warstwy prezentacji. Skryplety burzą ten podział. Powiedzmy sobie po prostu, że jest to przeszłość. Zamiast nich powinniśmy używać specjalnych znaczników EL i JSTL. Wspomniałem kiedyś, że JSP to tak naprawdę serwlet. Od strony technicznej dokument JSP przy pierwszym uruchomieniu jest przekształcany na serwerze do odpowiadającego im serwletu.




       
       Klient wysyła żądanie pobrania strony, które po przejściu przez serwer HTTP trafia do serwera aplikacji - Web server. Żądanie zostaje przekierowane do kontenera JSP, który znajduje się na serwerze aplikacji. Podczas pierwszego żądania pobrania strony JSP zostaje ona wysłana do translatora JSP. Translator generuje kod wynikowy w postaci klasy serwletu. Kod źródłowy jest przesyłany do kompilatora Java, gdzie zamieniamy jest na Java Byte Code maszyny wirtualnej. Od tej pory ten skompilowany kod czyli tak naprawdę serwlet jest zarządzany przez kontener serwletów.
Skompilowane strony JSP pozostają załadowane do maszyny wirtualnej Java i kolejne odwołania do tej samej strony nie wymagają przejścia przez fazę translacji.



      Obecnie technologia JSP ma wsparcie w postaci języka wyrażeń EL- Expression Language i standardowej biblioteki znaczników JSTL - JavaServer Pages Tag Library.EL i JSTL zastępują nam znaczniki, które za bardzo komplikują kod, a także mieszają logikę prezentacji i aplikacji.

Strony JSP mogą odwoływać się do obiektów predefiniowanych w skryptach :
  • request - wszystkie parametry wywołania strony JSP (HttpServletRequest)
  • response - reprezentuje odpowiedź zwracaną klientowi (HttpServletResponse)
  • out - reprezentuje stronę zwracaną klientowi (jsp.JspWriter)
  • session - reprezentuje sesję HTTP (http.HttpSession)
  • application - reprezentuje kontekst aplikacji (ServletContex)
  • config - konfiguracja serwletu (servletConfig)
  • pageContext - obiekty, które są w zasięgu widoczności bieżącej strony (jsp.PageContext)
  • page - reprezentuje bieżącą stronę (java.lang.Object)


      Przyjrzyjmy się skryptom JSP, których jak już wspomniałem nie należy używać. Skrypty są to :

  • <%= wyrazenie  %> - wyrażenia są one przekazywane na wyjście czyli okno przeglądarki
  • <% kod %> - skryplety są umieszczane wewnątrz metody service() serwletu
  • <%! kod %> - deklaracje są umieszczane wewnątrz klasy serwletu poza metodami
      Przykład wyrażenia: Przykład skrypletu: Przykład deklaracji:       JSP dostarcza dyrektyw czyli kilku różnych konstrukcji stosowanych w zależności od danej sytuacji. Istnieją ogólnie trzy główne typy dyrektyw:
  • page - pozwala m.in. na importowanie klasy, określić język użyty w skryplecie itp.
  • include - pozwala na dołączenie innego pliku do treści danej strony
  • taglib - jest związana z technologią JSTL, której przyjrzymy się później po omówienie EL


      Przykład dyrektywy page:




      Jak widzimy dyrektywa taka posiada pewne atrybutu, nie są to wszystkie atrybuty jakie może przyjąć.

      Oto najważniejsze ustawienia dyrektywy page:
  • contentType - określa typ MIME strony np. text/html
  • pageEncoding - kodowanie znaków na stronie
  • isErrorPage - określa czy dana strona jest stroną błędu
  • errorPage - określa ścieżkę do strony, która ma być wywołana  w razie błędu na tej stronie
  • session - określa czy na danej stronie jest wykorzystywane mechanizm sesji
  • import - pozwala na importowanie klas/pakietów, w celu późniejszego wykorzystania 
  • isELIgnored - określa, czy elementy języka wyrażeń EL mają być ignorowane na danej stronie

      Stwórzmy bardzo prostą aplikację w środowisku NetBeans. Klient wchodząc na stronę poda swoje imię i hasło w formularzu, po zatwierdzeniu danych zostaje wyświetlona strona z imieniem i datą logowania.

      Stwórzmy na początku stronę odpowiadająca za pobranie danych od użytkownika, nazwijmy ją loginpage.jsp:




      Strona index.jsp zostanie zmodyfikowana w ten sposób, aby wyświetlała login, który podał klient. Strona wykorzystuje bibliotekę JSTL, powiemy sobie o niej następnym razem. Następuje odczyt w pętli atrybutów sesji. Atrybut ma nazwę User i odwołujemy się do niego przez sessionScope.User .User jest kolekcją zawierającą obiekty klasy User. Zmienna var="user" przechowuje pobrany obiekt z kolekcji. Wyświetlenie nazwy użytkownika i daty logowania odbywa się bardzo prosto: ${user.name} ${user.t} .
 



       Stworzymy też serwlet odpowiedzialny za pobranie danych z formularza i przekierowania żądania do strony index.jsp. W serwlecie korzystamy z mechanizmu sesji. Zapisujemy w niej kolekcję przechowującą obiekty klasy User. Po tym następuje przekierowanie żądania do strony index.jsp.



      Obiekt klasy User będzie odzwierciedlać klienta, przechowując jego login, hasło i datę logowania. Taka klasa, która spełnia kilka konwencji głównie  takich jak bez parametryczny konstruktor, udostępnianie atrybutów po przez metody pośredniczące get i set nazywamy JavaBean - ziarno kawy. Jak spojrzymy na nasz serwlet to zauważymy, że ustawiamy w zasięgu sesji atrybut o nazwie User będący kolekcją typu ArrayList, przechowującą obiekty klasy User.

     


Pozostaje, także do skonfigurowania deskryptor wdrożenia:




   
 Nasza aplikacja wygląda w następujący sposób:

      Formularz logowania:


      Strona index.jsp, która reprezentuje wprowadzone dane:


   

      W następnych częściach przyjrzymy się EL - językowi wyrażeń, JavaBeans - ziarna kawy, akcjom JSP, standardowej bibliotece tagów JSTL, modelowi JSP 1 i JSP 2 czyli wzorcowi MVC.