Egy példányban futó Java program

egyGyakran észrevesszük, hogy a programok futtatásakor vannak bizonyos korlátok. Például egyszerre általában csak egyetlen telepítőprogram futhat egy operációs rendszeren. Vagy amíg fut egy program korábbi verziójának eltávolítása, addig nem futhat a program új verziójának telepítője. Vagy egy nagyobb erőforrás igényű program (periféria meghajtó program, képernyő videó+hang rögzítő, hardveres gyorsítást használó játékprogram) egyszerre csak egy példányban indítható el. Előfordulhat kategóriánkénti korlát is, például a különböző víruskereső programok általában „nem tűrik meg” egymást, kizárólagosságot „követelnek”.

Lássunk példát arra, hogyan kell készíteni egy példányban futó Java programot!

Néhány dolgot át kell gondolni:

  • Amikor először indítjuk el a programot, akkor olyan egyedi dolgot kell beállítani, ami mindvégig úgy marad, amíg a program fut. Ezt megtehetjük a memóriában, de megfelelő jogosultsággal futtatva a programot akár beleírhatunk a Windows rendszerleíró adatbázisába (Registry) is. Előbbi módszer platformfüggetlen lenne – ahogyan egy Java programhoz illik –, és az utóbbi megoldás pedig operációs rendszertől függne.
  • Amikor többedszer (második, harmadik… példányban) indítjuk el a programot, akkor ezt az egyedi dolgot észlelni kell és meg kell akadályozni a program másodszori, harmadszori elindítását. Hasznos, ha ezekben az esetekben kapunk hibaüzenetet, például: „This application is already running”.
  • Amikor a programot szabályosan állítjuk le, akkor a korábban beállított egyedi dolgot semmissé kell tenni. Ez biztosítja, hogy a program egymás után – egymással nem párhuzamosan, egymástól függetlenül – elindítható lesz.

A megoldás két részből áll. Ez a Java forráskód első része:

A program indulásakor le kell futni a fenti forráskódnak. A static blokk a konstruktor előtt hajtódik végre (például a modell vagy a nézet rétegben). A java.net csomag kötetlen ServerSocket osztályú ss nevű objektumát kell inicializálni helyben ( InetAddress.getLocalHost()) egy nem dedikált porttal ( 65001). Ez elsőre mindig sikerült és az objektum „beül a memóriába” egy nem blokkoló elven működő háttérszálon. Ha (többedszerre) nem sikerül létrehozni az objektumot, akkor – kezelve a kötelezően kezelendő kivételeket – hasznos jelezni ezt logban, konzolon vagy felbukkanó párbeszédablakban és a programból ki kell lépni (másképpen: a duplikált futtatását meg kell akadályozni).

Ez a Java forráskód második része:

A programból való szabályos kilépéskor le kell futni a fenti forráskódnak. Ez ellenőrzést követően lezárja az ss objektumot és kilép a programból. Például a main() metódusban, ha elfogynak az utasítások egy konzolos alkalmazásban, vagy GUI-s programban nyomógombra kattintás actionPerformed() esemény, vagy (fő)ablak bezárásának kísérlete WindowClosing() esemény.

A programot érdemes körültekintően tesztelni. Ha elrontjuk a fenti felsorolásban vázolt logikai működés végrehajtásának sorrendjét, akkor fejlesztés vagy tesztelés közben akár a számítógépet is újra kell indítanunk.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A Java EE szoftverfejlesztő tanfolyamunkon, a szakmai modul 5-8. óra Szálkezelés, párhuzamosság alkalommal megismerjük a megoldás elméleti hátterét és a 17-24. óra Socket és RMI alapú kommunikáció alkalommal többféle megvalósítást is kódolunk, tesztelünk.


Ajánljuk a Java EE szoftverfejlesztő tanfolyam kategóriából

“Egy példányban futó Java program” bejegyzéshez 5 hozzászólás

  1. Balázs: az egyik korábbi Java EE órán beszéltünk arról, hogy a chatprogramba beépíthető olyan korlát, hogy a szobákban hányan tudjanak belépni. Megpróbálnám megoldani ezt. Továbbgondolva Sándor fix korlát=1 megoldását módosítható korlát=n-re. Jó ötlet hozzá a ServerSocket használata?

    Válasz
    • András: ha a programodban minden szobában ugyanaz (statikus) a korlát, akkor a ServerSocket jó megoldás. Ha szobánként különböző korlátokat szeretnél, vagy esetleg a futás közben szeretnéd beállíthatóvá tenni a korlátot, akkor arra a jövő heti órán nézünk egy praktikusabb (dinamikus) megoldást.
      Addig is gondold át szálkezeléshez kötődő projektjeinket (a teljes Java forráskódokat az ILIAS-on találod).

      Válasz
  2. Sándor: az egyszerre egy példányban futó programhoz hasonló problémának gondolom azt, ha egy processz sokáig tart és meg kell várni, amíg befejeződik, mielőtt újra elindítható. Adódik egy olyan időszelet, amikor egy példányban megy a végrehajtás. Oké ez így?

    Válasz
    • Helyesen gondolod Bende. Az ILIAS-ban megtalálod az operációs rendszerek ütemezési problémáinál a szemaforkezelést. Az elv azonos azzal, amit leírtál. Ugyanott találsz hozzá mintaprogramokat is. A megvalósítás többféleképpen is lehet.
      Egy típusfeladat erre: egy mappa méretének kiszámítása. Ez több másodpercig szokott tartani. Konzolosan privilegizált szálkezeléssel célszerű megoldani. Ha GUI-s a program, akkor letiltjuk az ezt a funkciót indító nyomógombot, hogy amíg fut, addig ne legyen újraindítható ugyanarra a mappára. Ehhez kivételkezelés is kell, mert mindenképpen folytatódnia kell tudnia a programnak.

      Válasz

Szólj hozzá!