Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /home/www/novacisko.cz/subdomains/bredy/init.php on line 11

Warning: mysql_connect(): Headers and client library minor version mismatch. Headers:50562 Library:100020 in /home/www/novacisko.cz/subdomains/bredy/init.php on line 11

Warning: Cannot modify header information - headers already sent by (output started at /home/www/novacisko.cz/subdomains/bredy/init.php:11) in /home/www/novacisko.cz/subdomains/bredy/index.php on line 38
Jak na destruktory v Javě - Bredyho blog - Ondřej Novák
Bredyho blog - Ondřej Novák

Jak na destruktory v Javě

Chybí vám destruktor v Javě. Úplně jej nahradit neumíme, ale jisté řešení by se našlo


Taky už jsem zatoužil po destruktorech v Jave. Zrovna v projektu, na kterém pracuji, jsou třídy manipulující se soubory. A jak známo, soubory by se měly zavírat a pokud byl soubor exkluzivně uzamčen, tak neodemknout jej je často cestou do pekel.

Ptáte se proč? Vždyť destrukci objektů má na starost garbage collector. Problém je v tom, že garbage collector se nespouští ihned po opuštění objektu, ale... až někdy. A to slovo někdy může taky znamenat nikdy. Jak je to možné? Pracujete s exkluzivně zamčeným souborem, pak jej opustíte a následně, z jiné části programu jej znovu chcete otevřít exkluzivně. A tu najednou začne váš program čekat. A čekat a čekat a čekat... až garbage collector uvolní minulou instanci souboru. Jenže ten si dává na čas, vlastně usoudí, že se nemusí spouštět, jelikož paměti je ještě dost. A krásný deadlock je na světě.

Abych emuloval destruktor, zavedl jsem rozhraní Destroyable (po vzoru ostatních ...able tříd).

public interface Destroyable {

public void destroy();
}

Skoro na tom nic není. Co mi to ale přináší? Každý objekt, který je citlivý na včasné zničení tedy implementuje toto rozhraní. To ale nestačí. Musíme ještě emulovat scope jako například v C++. K tomu nám postačí třída AutoDestroy

public class AutoDestroy implements Destroyable {

Vector<Destroyable> objects;

public void destroy() {

Enumeration<Destroyable> iter = objects.elements();
while (iter.hasMoreElements()) {
iter.nextElement().destroy();
}
objects.clear();
}

public Destroyable add(Destroyable object) {
objects.add(object);
return object;
}

protected void finalize() {
destroy();
}
}

AutoDestroy je třída, která registruje objekty typu Destroyable. Samotná třída také implementuje toto rozhraní. To umožňuje jednotlivé instance řetězit.

K uvolnění celého stromu pak stačí, aby někdo zavolal destroy() na kořenový objekt třídy AutoDestroy.

Je to lepší, nemusíme hlídat životnost všech objektů. Každý objekt prostě při vzniku zaregistrujeme do instance třídy AutoDestroy a pak už zničení zajistí ten, kdo ničí tuto instanci.

Abysme měli programování co nejpohodlnější, napíšeme si ještě takový mustr

public void foo(...)
{
AutoDestroy scope = new AutoDestroy();
try {
MyFile aa = new MyFile...
scope.add(aa);
MyFile bb = new MyFile..
scope.add(bb);
...
...
} finally {
scope.destroy();
}

Ať už blok ukončíme jakkoliv, vždy se provede sekce finally. A ten zajistí zničení scope.

Co dát do destroy()?

Pokud zároveň programujete v C++, tak destroy() je pro vás proste destruktor, jako v C++. Měli byste zavolat destroy() všech objektů, které implementuji Destroyable. Dále přerušit všechny reference nastevním na null. Zavřít všechny zdroje (soubory, zámky, atd).

Metoda destroy() by měla zničit zejména sama sebe. Ostatní závislé objekty by měla ničit nepřímo pomocí volání destroy() na ničeném objektu.

Problémy

Nic není bez problémů a i tady lze očekávat nějaké obtíže. Tím že zavádíme explicitní destrukci objektu, popíráme implicitní destrukci pomocí garbage collectoru. Toho odsouváme do role pouhého likvidátora přidělené paměti. Explicitní destrukcí objektu se také vystavujeme riziku práce se zničeným objektem. To může v Javě vést většinou k výjimce NullPointerException.

Dalším problémem jsou sdílené objekty, například sdílený soubor. Tam už nemůžeme destroy() volat bez rozmyslu. Díky tomu, že nám Java neřekne, kdo ještě objekt sdílí, nemůžeme určit okamžik, kdy destroy má skutečně objekt zničit. Co takhle zavést počítání referencí...?

Závěr

I tak si myslím, že destruktor v Javě má místo. Tohle je docela užitečné řešení. Pokud všechny závislé objekty ničíme tímto způsobem, máme likvidaci objektů ve spolehlivě svých rukou.

vytvořeno: 22.10.2007 23:06:30, změněno: 23.10.2007 01:20:22
Jsou informace v článku pro Vás užitečné?
  • (0)
  • (3)
  • (3)
  • (0)
  • (9)
Nick nebo OpenID
Vzkaz
 
25.7.2016 18:41:43

rJytZsZrgT

الحجاز الحجاز هي مفخرة لكل من كان حجازي او سكن بها او ينتمي بترابها فهي منها خرج الدين الاسلامي وخاتم الانبياء وفي ترابها دفن سيد الخلق حيث يوجد بها أحفاد الحبيب المصطفي وأحفاد صحابته ؃„‡™Â§Ã™ÂÂرامفÙÂÃي بذالك الحجاز وأهلها فخر وإحترام لكل مسلم في بقاع الارض ويكفي حق الحاقدين علي الحجاز وأهلها

Podobné články

GarbageCollector v C++, prototyp

Neustále slýchám, jak v C++ chybí Garbage Collector. Ač si o tomto nástroji myslím své, a v zásadě jsem proti zavedení GC v C++, přijal jsem tyto nářky jako výzvu.

Automatické klonování objektů v C++ II

Dneska se podíváme jak klonovat pomocí clone_ptr (ClonePtr)

Jak sdílet prostředky (resources) v C++

Nemnohokrát jsem řešil v programech psaných v C++, jak sdílet prostředky (resources), jinými slovy, jak zajistit, že jedinečné prostředky budou uvolňovány až v okamžiku, kdy je nikdo nepotřebuje. Podívejme se na jednoduché řešení.

Obecné OOP


Garbage collector - automatický úklid objektů v C++

Článek navazuje na GarbageCollector v C++, prototyp, kde jsme si představili prototyp třídy provádějící automatický úklid objektů známy jako "garbage collector". Dnes si ukážeme další verzi, nazvěme ji "alfa"
Reklama: