Generics ve Reflection ile genelleştirilmiş dizi yaratma

Daha önceden buna benzer bir kodu Java 1.4 ile generics kullanmadan yazmıştım. Ancak Generics’in sağladığı özelliklerle tip dönüşümü kodunu metod içine alarak dışarıya tip güvenli bir metod sunabildim. Şimdi örnek kullanım ile metodumuzu görelim.

import java.lang.reflect.Array;

public class GenericArrayDemo {

	public static void main(String[] args) {
		System.out.println(getArray(String.class,10).getClass().getSimpleName());
		String theArray[] = getArray(String.class, 10);
	}

	@SuppressWarnings("unchecked")
	public static <T> T[] getArray(Class<T> clazz,int size) {
		T theArray[] = (T[])Array.newInstance(clazz, size);
		for(int i=0;i<size;i++)
			try {
				theArray[i]=clazz.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		return theArray;
	}
}

Burada çıktı olarak String[] üretilmekte ve oluşan dizi direk ve yalnız String dizisine atanabilmektedir. Şimdi örneğimizi genişletelim ve metodun sadece Number sınıfının alt sınıflarını üretebilmesini sağlayalım.

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class GenericArrayDemo {

	public static void main(String[] args) {
		/* Bu satırlar artık Number altsınıfı beklediğimizden hata alacaktır.
		System.out.println(getArray(String.class,10).getClass().getSimpleName());
		String theArray[] = getArray(String.class, 10);
		*/
		System.out.println(getArray(Double.class,10).getClass().getSimpleName());
		Long theArray[] = getArray(Long.class, 10);
		for (Long long1 : theArray) {
			System.out.println(long1);
		}
	}

	@SuppressWarnings("unchecked")
	public static <T extends Number> T[] getArray(Class<T> clazz,int size) {
		T theArray[] = (T[])Array.newInstance(clazz, size);
		for(int i=0;i<size;i++)
			try {
				/* 
				 * Number alt sınıfları parametresiz constructor
				 * içermediği için 0 ile ilklendiriyoruz
				 */
				Constructor<T> constructor=clazz.getConstructor(String.class);
				theArray[i]=constructor.newInstance("0");
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		return theArray;
	}
}

Bu metod ise Double[] ve ardından 10 adet sıfır yazdırmaktadır. Artık Number alt sınıfı beklediğinden bir önceki örnekteki satırlar çalışmamaktadır. Burada sınıfa ait String parametresi alan Constructor üretilmekte ve o şekilde ilklenmektedir.

Bunu benim kullanım amacım veritabanında çağırılan stored procedure sonuçlarını uyumlu bir sınıf dizisine eşleyebilen genel bir metod yazmak idi. Belki daha farklı kullanım amaçları da olabilir.


Yayınlandı gezegen, java

29 Nisan 2009

Posted In: Gezegen, java

Gerçek zamanlı bir Linux masalı

Cahil Cesareti
Bir gün Linus adında bir genç, yaşına başına bakmadan bir işletim sistemi çekirdeği (kernel) yazmaya başlamış. Cahil cesareti diye buna deniyor herhalde. Başlamış kodlamaya... Yazdıkça yazmış, yazdıkça yazmış. O sırada bir kahkaha sesi duyulmuş. Linus umursamamış, yazmaya devam etmiş. Üç bin, beş bin satır derken kodlar çoğalmaya, çalışan birşeyler ortaya çıkmaya başlamış. Bu sefer 'mikro kodla' diye bir ses duyulmuş. Sağa sola bakınmış, kimseyi görememiş. Yazmaya devam etmiş. Sonunda çalışan bir çekirdek çıkmış ortaya. Bunu arkadaşlarına göstermiş, arkadaşları çok beğenmiş. Hatta bazıları makinesine kurup kullanmaya başlamış. O bilmiş ses bi daha duyulmuş: 'mikro kodla'

Linus sağa sola bakınmış kimse yok. Başını kaldırıp kürsüye bakınca orada oturmakta olan Tanenbaum Hoca'yı görmüş.

[ Tanenbaum Hoca ] Evladım, kaç yılındayız biz?
[ Linus ] 1992
[ Tanenbaum Hoca ] 1992 yılında monolitik çekirdek yazılır mı? Ne bulduysan koymuşsun çekirdeğin içine... Kim yapacak bu kodun bakımını? Ya bi hata yaparsan, bütün sistem çöker valla
[ Linus ] Hocam iyi ama...
[ Tanenbaum Hoca ] Mikro çekirdek yazacaksın. Çekirdek dediğin ayak işlerine bakmaz. Dosya sistemini, hafızayı filan bırak da hizmetçiler halletsin. Yoksa senin çekirdek, başkalarının hizmetçisi olur.
[ Linus ] Hocam, güzel diyorsun da bak Richard Stallman Abi mikro çekirdek yazacam diye yıllarını harcadı, saç sakal birbirine karıştı ama hala ortada birşey yok. Emacs bile bitti, çekirdek bitmedi.
[ Tanenbaum Hoca ] Bak hala konuşuyor. Dua et benim öğrencim değilsin, yoksa sınıfta kalmıştın.

Linus, 'bu akademisyen tayfası adam olmaz' diye içinden geçirip, bildiği gibi yoluna devam etmiş. Sonunda ortaya oldukça yetenekli ve hızlı bir çekirdek çıkmış. GNU araçları ile de bu çekirdeği birleştirince GNU/Linux işletim sistemi doğmuş. Bu işletim sistemi çok tutmuş, her yerde kullanılmaya başlanmış.


Mühim Adamlar
GNU/Linux'un başarısı, hard real-time sistemler tasarlayan mühim adamların kulağına gitmiş. 'Şu GNU/Linux'u bir de biz görelim, belki işimize yarar' demişler. Toplanıp Linus'u ziyarete gitmişler.

[ Mühim adamlar ] Slm
[ Linus ] Slm
[ Mühim adamlar ] Senin çekirdeği, bizim işlerde kullanmak istiyoruz. Sence olur mu?
[ Linus ] Ben çekirdeğime güveniyorum. Her işin üstesinden gelebilir
[ Mühim adamlar ] Hmm, tamam öyleyse bir deneme yapalım. Şimdi ben şu topu havaya atacam, senin çekirdek yere düşmeden vuracak, tamam mi?

Mühim adam topu havaya atmış, 'pat'... Çekirdek anında havada vurmuş topu.

[ Mühim adamlar ] Hmm, güzel... Bir deneme daha yapalım.

Bir top daha atmış, 'pat' vurmuş. İki, üç derken sıra onüçüncü topa gelmiş. Mühim adam topu havaya atmış, çekirdekte hiç bi hareket yok. Herkes şaşkın birbirine bakınmış. Linus çekmiş çekirdeği kenara.

[ Linus ] Hayrola?
[ Çekirdek ] İşim vardı, topa bakamadım
[ Linus ] Nasıl bakamadın?
[ Çekirdek ] Abi, önemli işim vardı. Kesip topa bakamadım
[ Linus ] Dalga mı geçiyorsun sen benle? Bunlar mühim adamlar. Ne işin varsa kesip bunlarınkine bakacaksın
[ Çekirdek ] Kritik bölgedeyken nasıl keseyim işi
[ Linus ] Keseceksin, pre-emptive olacaksın
[ Çekirdek ] Sen bilirsin abi

Linus, mühim adamlara dönüp 'tamam hallettim sorunu, bi daha olmayacak böyle birşey' demiş. Yeniden başlamışlar top atmaya. Çekirdek pek bi pre-emptive hareket etmiş başlarda. Baya bi top vurmuş ama doksan dokuzuncu topta yine kaçırmış.

[ Mühim adamlar ] Hmm, bu olmamış, bizim işleri beceremez

deyip gitmişler. Linus ve çekirdek kalmış başbaşa.

[ Linus ] Niye kesmedin yaptığın işi
[ Pre-emptive çekirdek ] Bu sefer gerçekten çok önemli işim vardı, gerçekten kesilecek gibi değildi
[ Linus ] Ben sana gösteririm önemli işi. Seni Ingo Molnar'a göndereyim de, herbir yerini un ufak etsin. Kesilemeyecek işin kalmasın
[ Pre-emptive çekirdek ] Ama Tanenbaum Hoca demişti sana. Yıktın bütün işleri bana, hangisine bakacağımı...
[ Linus ] Sus!


Bu işi çözse çözse Kerim Yağmur çözer
Bu arada mühim adamlar da sonuçtan memnun değilmiş. Kendi aralarında durumu değerlendirmeye başlamışlar.
[ Mühim adam 1 ] Yok, bu çekirdek bizim işi görmez
[ Mühim adam 2 ] Evet görmez
[ Mühim adam 1 ] Halbuki üzerinde ne de güzel yazılımlar çalışıyordu. İşimizi görseydi, hepsi elimizin altında olacaktı
[ Mühim adam 3 ] Öyle ama monolitik yazmış çekirdeği. Bi sürü kritik bölge vardır kodda
[ Mühim adam 4 ] Evet. Kritik bölgeye girdi mi, çıkana kadar top çoktan yere düşer.
[ Mühim adam 1 ] Kritik bölgedeyken işi yarım bırakıp bizimkine bakamaz mı?
[ Mühim adam 3 ] Teoride olur ama bütün kritik bölge kodlarını baştan yazmak lazım. Çoook uzun iş ve yine de güven olmaz
[ Mühim adam 1 ] Öyleyse bu iş yatar, eski sistem devam ediyoruz
[ Mühim adam 4 ] Bi de Kerim Yağmur'a sorsak. O teknik konularda iyidir, belki aklına bir şey gelir
[ Mühim adam 3 ] Hmm soralım

Toplanıp hep birlikte Kerim Yağmur'a gitmişler.
[ Mühim adamlar ] Slm Kerim, bizim bir sorun vardı
[ Kerim Yağmur ] Evet?
[ Mühim adamlar ] Güzel bir işletim sistemi var, GNU/Linux Bizim işlerde kullanmayı düşündük ama çekirdek monolitik. Milyonlarca satır kod var içinde. İşleri toparlayıncaya kadar top yere düşüyor.
[ Kerim Yağmur ] Hmm, öyleyse QNX kullanın
[ Mühim adamlar ] QNX kullanıyoruz zaten ama GNU/Linux üstünde çok güzel yazılımlar var, onları istiyoruz
[ Kerim Yağmur ] Siz şimdi GNU/Linux üstünde çalışan servis ve yazılımları mı istiyorsunuz yoksa yeni bir gerçek zamanlı işletim sistemi mi?
[ Mühim adamlar ] Asıl istediğimiz servis ve yazılımlar
[ Kerim Yağmur ] Öyleyse iş kolay. Yazarız bir gerçek zamanlı mikro çekirdek, GNU/Linux'u onun üzerinde servis olarak çalıştırırız
[ Mühim adamlar ] O zaman GNU/Linux bizim işleri yapabilecek mi
[ Kerim Yağmur ] Sizin işleri, yazacağımız gerçek zamanlı mikro çekirdek halledecek ama GNU/Linux'da bir yanda çalıştığı için onu da kullanabileceksiniz
[ Mühim adamlar ] Linus bozulmasın kendi işletim sisteminin servis olarak çalışmasına
[ Kerim Yağmur ] Yok yahu, niye bozulsun
[ Mühim adamlar ] Adam bi garip. Zaten 'mikro' kelimesini duyunca gözü seğirmeye başlıyor, sinirli oluyor
[ Kerim Yağmur ] Tamam canım, biz de mikro değil, nano çekirdek deriz. Adını da ADEOS koyarız.

O sırada bir kahkaha sesi duyulmuş.

26 Nisan 2009

Posted In: linux, lkd, realtime

Shell Scripting III – Linuxta İşlemler

Bir önceki yazımda basit dizin ve dosya yönetim komutları üzerinde durmuştuk. Dosya ve dizin yönetimi Linux Shell’in en önemli görevlerindendir. Fakat uygulamalarımızı yazmaya başlamadan önce bakmamız gereken Shell’in bir kaç  önemli özelliği daha bulunuyor. Bu yazı dizimizde Linux sistem yönetimi ile ilgili bilgilerimizi paylaşacağız. Programları İzlemek Linux sistem yöneticisinin en önemli görevlerinden birisi sistemde çalışan […]

26 Nisan 2009

Posted In: BSD, gnu, İşlem, linux, process, Shell Scripting, unix

Geocities kapılarını kapatıyor

Uzun zamandan beri Türkiye’de mahkeme kararıyla kapalı olan Geocities hizmeti yahu tarafından durduruluyor. Yeni kullanıcı kayıtlarına kapatılan site yıl içinde tamamen kapanacak. 90’ların sonunda oldukça moda olan ve zamanının ötesindeki online editörüyle benim gibi pek çok insanı “1-2 tıkta” web sitesi sahibi eden Geocities de Yahoo Briefcase ile aynı kaderi paylaşıyor. O zamanlar için “aşmış” sayılabilecek bu iki hizmet de malesef zamana yenik düştü ve değerini yitirdi.

Güle güle Geocities!


Yayınlandı gezegen, internet, yahoo

24 Nisan 2009

Posted In: Gezegen, internet, yahoo

OpenOffice.org’un geleceği belirsiz.

Florian Effenberger, uluslararası OpenOffice.org projesınden sorumlu kişi. Linux topluluğu Effenberger ile iletişime geçti ve kendisine Oracle ile alakalı bir kaç soru sordu. Linux Topluluğu : Ücretlerini Sun’dan alan geliştiriciler, Oracle tarafından işten çıkarılacak mı? Florian Effenberger : Oracle ile Sun arasında yapılan anlaşma tam olarak bilinmiyor. Bir çok analist şu anda bir çok asılsız spekülasyonlar […]

24 Nisan 2009

Posted In: Florian Effenberger, linux, OpenOffice.org, Oracle, StarOffice, Sun

Gerçek zamanlı (real-time) sistem nedir?

İşlerini, tam zamanında yapan sisteme, gerçek zamanlı sistem denir. Dolayısı ile tam zamanında yapılması gereken işlerimiz yoksa, gerçek zamanlı bir sisteme de ihtiyacımız yok demektir.

Bir işin, tam zamanında yapılması gerekiyorsa bu iş, zaman açısından kritik bir iştir. Zaman açısından kritik işler, zamanında yapılamazlarsa başarısızlıkla sonuçlanmış olurlar.

Örneğin yemek pişirmek, zaman açısından kritik bir iştir. Bir yemek, olması gerekenden az veya çok pişirilirse, başarısızlıkla sonuçlanmış demektir. Dolayısı ile iyi aşçılar, gerçek zamanlı çalışan organik sistemlerdir.

Yalnız bu tanımda dikkat edilmesi gereken bir şey daha vardır. O da tam zamanında ifadesi ile kastedilen işin bitirilme anının, aslında akıp giden zaman içinde bir anı değil, bir süreyi ifade ettiğidir.

180°'de 45 dakika pişmesi gereken levrek buğulamayı, 44. dakikada veya 46. dakikada fırından çıkarırsak aslında hatalı birşey yapmış olmayız çünkü bu ufak sapma, kabul edilebilir düzeydedir ve kimse kalkıp da 'bu yemek iyi pişmemiş' demez. Eğer yemeği yapan, işinin ehli bir aşçı ise yemeğin, çiğ veya yanık şekilde önümüze gelmeyeceğini biliriz.

Gerçek zamanlı sistemler, latency terimi ile ifade edilen bu sapmaların, belli bir değerden küçük olacağını bize garanti ederler.


Soft Real-time ve Hard Real-time
Aşçı denilen organizmaların, yemeklerin pişirilme süreleri konusunda ne kadar hassas sistemler olduğuna değinmiştik. Peki ama aşçılar hiç mi hata yapmaz? Bir aşçı, arada bir hata yapıp yemeği hafif yaksa ne olur?

Ne olacağı, bu aşçının yemeklerini kimin yediğine bağlıdır. Eğer Sirkeci'de bir lokantada çalışıyorsa (ki burada kasdedilen Konyalı'nın aşçıları değildir) hafif yanık yemeği müşteriye kakalarsın gider, en kötü ihtimal o müşteri, bir daha lokantaya uğramaz. Yani çok da dert değil, müşterinin suyu mu çıktı? Bu gelmezse öbürü gelir.

Eğer söz konusu aşçımız, sarayın aşçıbaşısı ise ve yemeklerini yiyen padişah ise, işte o zaman durum kritiktir, hayati bir durum söz konusudur. Artık aşçıya reset mi atarlar, kazığa oturtup Youtube'da videosunu mu yayınlarlar bilemiyorum.

Birinci aşçı organizması, soft real-time sisteme; ikinci aşçı organizması, hard real-time sisteme örnektir.

İşlerimizi, belli bir sapmayı aşmayacak şekilde yapacağını bize garanti eden sistemimiz, arada sırada bu sözünü yerine getiremiyor ama bu kusurun, göz ardı edilebilir sonuçları oluyorsa, söz konusu sistem soft real-time'dır.

Sistemimiz, garanti edilen sapma aralığının asla ve asla dışına çıkmıyorsa ve bu sistemde çalışan işler, sapma aralığının dışına çıkıldığında kabul edilemez sonuçlar doğuruyorsa, sistemimiz hard real-time'dır.


Jitter
Aşçıların bir tipi vardır ki buna da jitter denir. Mutfak havalandırmasının iyi olmamasından dolayı sürekli buhar altında kalan ve yamaklığı sırasında her gün zorla üç çuval patates soydurulan aşçılar arasında sıklıkla bu tipe rastlanır. Jitter'lar yemeği, bazen az pişmiş bırakır, bazen hafiften yakarlar. Ama bazen de bakarsın en mükemmel yemekle çıkıp gelirler.

Bu tip aşçılar lokanta sahipleri tarafından pek sevilmez ve istenmezler çünkü müşteriyi kaçırırlar. Yemeği hep pişkin yapsa sorun değil, o zaman en azından pişkin yemek seven müşteriler sürekli gelir. Sürekli az pişmiş bıraksa da sorun değil, o zaman da az pişmiş yemek seven müşterilerle idare edilir. Mutfaktan ne çıkacağı belli olmayınca, müşterinin hiçbir türü kalmaz.

Bu nedenle gerçek zamanlı sistemlerde jitter sevilmez. Sapma olacaksa bile (ki mutlaka olur, bu sadece ne kadar hassas ölçüm yaptığımıza bağlıdır) en azından sapmaların hep aynı yönde ve benzer oranlarda olması istenir; tabii garanti edilen aralığı da aşmamak koşulu ile...

Gerçek zamanlı sistem hızlı mı olmalı?
Aşçımız, evde çocuklarına yemek pişiren bir anne ise hızlı olmasına gerek yoktur, üç tencereyi kontrol altında tutabilmesi yeterlidir. Ama onlarca yemeğin aynı anda hazırlanması gereken bir lokanta söz konusu ise bunca yemeği aynı anda kontrol edebilecek ve hepsinin tam kıvamında pişmesini sağlayabilecek hızlı bir aşçıya ihtiyaç vardır.

Tabii aşçının hızlı olması, yemekleri tam kıvamında pişireceğinin garantisi değildir. Ama aynı zamanda, beş kap yemeği tam kıvamında pişirebilen bir aşçının, yeterince hızlı değilse on kap yemeği tam kıvamında pişireceği de garanti değildir.

Gerçek zamanlı sistemler, kaldırabileceği oranda iş yükleri varsa gerçek zamanlı olma özelliklerini koruyabilirler. Dolayısı ile gerçek zamanlı bir sistem kurgulanırken iş yükü, baştan kesin bir doğrulukla hesaplanmalıdır.


Gerçek zamanlı sistemde tampon (buffer) kullanımı
Börekçiler tampon ile çalışır. Bi sabah börekçiye gidip 'peynirli var mı' diye sorulduğunda '10 dakika sonra hazır' cevabı alınabilirken, ertesi gün tezgahın üzerinde tonlarca peynirli börek bulunabilir. Dolayısı ile 'bugün kesin peynirli börek yiyecem' diye börekçiye gidip oturduğumuzda böreğin ne zaman önünüze geleceğinden asla emin olamayız. Bu nedenle hard real-time sistemlerde tampon kullanılmaz.


Pre-emptive nedir?
Aile terbiyesi almamış aşçıya, pre-emptive denir. Bu aşçı tipi, yemeklerine özen göstermez, kimini yakar, kimini çiğ bırakır. Yemek diye çiğ tavuk sunduğu bile görülmüştür ama ne zaman ki kapıdan yağlı bir müşteri girer, hemen Oktay Usta kesilir. Bu müşterinin yemeklerine özel bir hassasiyet gösterir, mükemmel olması için gayret eder. Tabii bu tip bir aşçı bozuntusunun ne derece mükemmel(!) iş yapacağı malumunuz. O nedenle hard real-time dünyasında yeri yoktur, adam yerine konulmaz.

Bu yazıdan çıkarılacak sonuca gelirsek, son söz olarak şunu diyebiliriz: 'Hamburger yemeyin'

21 Nisan 2009

Posted In: linux, lkd, realtime, rtai

AmaterasUML: Açık kaynak ve uyumluluk üzerine bir hikaye

Bytecode uyumluluğu ve API uyumluluğu

Java kodlarımızı derlerken derleyiciye -source ve -target parametrelerini vererek belli bir sürüme ait bytecode a derleyebiliyoruz. Tabi burada yeni sürüme ait DİL özelliklerinden feragat ediyoruz. Örnek olarak kodumuzu Java 1.4 için derlemek istersek Generics, Boxing gibi özellikleri kullanamayız. Ancak bu işlem aynı garantiyi JDK’nın sunduğu API için sağlamamaktadır. Örnek olarak Java6 ile yeni gelen bir sınıfı kullanıp Java5 ile çalıştırdığımızda ClassNotFoundException, Java6 ile yeni gelen metodu Java5 ile çalıştırdığımızda NoSuchMethodError hatası alırız. Bu durumda en emin yöntem geliştirirken hedef aldığımız minimum majör sürümü (Örn: Java5) kullanmamız olacaktır. Artık pek çok IDE proje bazında  kullanılan JRE/JDK sürümünü seçmemize izin vermektedir.

AmaterasUML Eclipse eklentisini Java5 ile çalıştıtırken aldığım hata

Gelelim hikayemizin gelişme bölümüne. Eclipse için geliştirilmiş açık kaynaklı bir UML eklentisi olan AmaterasUML tam olarak da bu sorundan müzdarip. Eklenti ikili dosyaları Java5 sisteminde çalışmasına rağmen UML oluşturması için sınıfları ekrana sürüklediğimizde java.lang.NoSuchMethodError: java.util.Arrays.copyOf([Ljava/lang/Object;I)[Ljava/lang/Object; hatası alıyoruz. Bunun sebebi ise Arrays.copyOf() metodunun Java6 ile yeni gelmiş olması.

Nasıl düzelttim?

Gelelim çözüme. Şanslıyız ki eklentimiz açık kaynak kodlu. Aslında bahsetmedim ama sorunun kaynağını bulabilmek için de projenin kaynak kodunu inceledim. Şimdi tek kalan şey bunu düzeltmek, test etmek ve geliştiriciye yollamak. Bunun için Proje kodunu SVN’den indirip açtım ve JDK 1.0’dan beri varolan System.arraycopy() metodunu kullandım. Daha sonra düzenlenmiş kod ile eklenti dosyasını yeniden oluşturup kendi oluşturduğum dosyadan kurdum. Ve, evet eklenti olması gerektiği gibi çalıştı ve sınıflarda UML diyagramı oluşturdu. Ardından yamayı oluşturarak projenin ulaştığım iki sitede (Sourceforge ve Java.net) yer alan hata kayıt sistemlerine bildirdim.

Hata Kayıtları


Yayınlandı eclipse, gezegen, java

20 Nisan 2009

Posted In: eclipse, Gezegen, java

Evince ile özgür PDFler

Geçenlerde elime yazdırma korumalı bir PDF geçti. O an elimde sadece Acrobat Reader olduğu için yazdırma imkanım olmadı. Ancak GNOME masaüstünde kullandığım Evince’in bunu bir şekilde aşabileceği düşüncesi oluştu. Ne de olsa ekrana gösteriyorsa yazdırabilirdi de. Evince kaynak kodunu incelerken bunun /apps/evince/override_restrictions anahtarıyla kontrol edildiğini farkettim. Üstüne üstük bu anahtarın varsayılan değeri true idi. Bunun düşünülmüş olmasına şaşırmadan PDFyi açtım ve dosyaya yazdır seçeneği ile yeniden kısıtsız PDF olarak oluşturdum. Bu adımdan sonra oluşan PDFyi Acrobat Reader ile yazdırabildim. Eğer bu ayar dağıtımınızda varsayılan olarak true değilse ekrandaki gibi değiştirebilirsiniz.gconf3


Yayınlandı gezegen, linux, pdf

17 Nisan 2009

Posted In: Gezegen, linux, pdf

Yeditepe Üniversitesi seminerinin ardından

Yeditepe Üniversitesi’n’de verdiğim “Açık Kaynak Kodlu Yazılım Geliştirme” semineri benim için bir ilkti. Daha önceden bu tarz bir seminer hiç vermemiştim. Ancak kendi adıma iyi geçtiğini düşünüyorum. İyi bir başlangıç iyi bir tecrübe oldu. Çok kalabalık bir grup olmasa da az sayıda insana da bilgi verebilmiş, açık kaynak kodlu projelere katılmayla ilgili heveslendirebildiysem ne mutlu bana. Buradan gayreti için Yeditepe Üniversitesi Bilgisayar Topluluğu başkanı Zafer ÇAKMAK’a teşekkür etmek isterim.

Şimdi darısı önümüzdekinin belki de yenilerinin başına.

Not: Seminer sunumuna yeni açtığım Verdiğim Seminerler sayfasından erişilebilir.


Yayınlandı gezegen, linux, seminer, yazılım

17 Nisan 2009

Posted In: Gezegen, linux, seminer, yazılım

Singleton Pattern üzerine

Singleton pattern kullanım amacı bir sınıfın kısıtlı nesnesini (hatta çoğunlukla tek) tek bir yerden yaratılması amacıyla kullanılmaktadır.  Şimdi bunu sağlayan Singleton sınıfı kodunu görelim. (Kod 1)

public class Singleton {
	private static Singleton theInstance = new Singleton();
	// Sınıf yüklendiğinde yaratılan tekil nesne

	public static Singleton getInstance() {
		// Dışarıdan nesne almak için bu metodu kullanacağız.
		return theInstance;
	}

	private Singleton() {
		// Constructor private tanımlansın ki dışarıdan erişilemesin.
		System.out.println("constructor");

		//Constructor 100 ms. bekleme gibi bir "iş" yapsın.
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Burada sınıfın nesnesine sadece getInstance() metodu ile erişilebilecektir. Ccnstructor 100 ms. gibi “makul” bir süre beklemektedir. Bu sınıftan nesneleri yaratan sınıfımızın kodunu da inceleyelim. (Kod 2)

public class SingletonTest {

	private static Singleton singletona, singletonb;

	public static void main(String[] args) {
		singletona = Singleton.getInstance();
		singletonb = Singleton.getInstance();
		System.out.println(singletona == singletonb);
	}

}

SingletonTest sınıfını çalıştırdığımızda aşağıdaki gibi bir çıktı vermektedir.

constructor
true

Görüldüğü üzere kodumuz amacına ulaşmış constructor 1 defa çağırılmıştır. Ancak bu yöntemde Singleton sınıfının nesnesi sınıf yüklendiği anda ilklenmektedir. Şimdi bu ilklemeyi ihtiyaç anına bırakalım (Lazy initilization). Yeni Singleton sınıfımız şu şekilde oluşacaktır. (Kod 3)

public class Singleton {
	private static Singleton theInstance;
	// İhtiyaç anında yaratılacak nesne

	public static Singleton getInstance() {
		// Dışarıdan nesne almak için bu metodu kullanacağız.
		// Eğer nesnemiz yaratılmamış ise yaratalım.
		if (theInstance == null) {
			theInstance = new Singleton();
		}
		// Şu an ya da önceden yaratılan nesneyi döndürelim.
		return theInstance;
	}

	private Singleton() {
		// Constructor private tanımlansın ki dışarıdan erişilemesin.
		System.out.println("constructor");

		// Constructor 100 ms. bekleme gibi bir "iş" yapsın.
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Bu şekilde de programımızı çalıştırdığımızda aynı çıktıyı vermekte ve beklenen şekilde işlemektedir. Şimdi SingletonTest sınıfını biraz değiştirelim ve getInstance() birden çok threadden çağırıldığında ne yapıyor onu görelim. (Kod 4)

public class SingletonTest {

	private static Singleton singletona, singletonb;

	public static void main(String[] args) {
		// getInstance() iki ayrı thread ile çağırılsın.
		Thread threada = new Thread() {

			@Override
			public void run() {
				singletona = Singleton.getInstance();
			}

		};
		threada.start();

		Thread threadb = new Thread() {

			@Override
			public void run() {
				singletonb = Singleton.getInstance();
			}

		};
		threadb.start();

		// Her iki thread tamamlanana kadar beklensin
		while (!(threada.getState() == Thread.State.TERMINATED && threadb
				.getState() == Thread.State.TERMINATED))
			;

		System.out.println(singletona == singletonb);
	}

}

Çıktımıza göre buu sefer sapıttı sanırım.

constructor
constructor
false

Evet constructor iki defa işledi ve bize iki ayrı nesne üretti. Şimdi ilklendirmemizi thread-safe hale getirelim. Bunu da getInstance() metodunu synchronized olarak tanımlayarak yapacağız. (Kod 5)

public class Singleton {
	private static Singleton theInstance;
	// İhtiyaç anında yaratılacak nesne

	public static synchronized Singleton getInstance() {
		// Dışarıdan nesne almak için bu metodu kullanacağız.
		// Eğer nesnemiz yaratılmamış ise yaratalım.
		// Metodu synchronized yaparak sayesinde aynı anda sadece bir yerden
		// çağırılmasını garanti ettik.
		if (theInstance == null) {
			theInstance = new Singleton();
		}
		// Şu an ya da önceden yaratılan nesneyi döndürelim.
		return theInstance;
	}

	private Singleton() {
		// Constructor private tanımlansın ki dışarıdan erişilemesin.
		System.out.println("constructor");

		// Constructor 100 ms. bekleme gibi bir "iş" yapsın.
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Evet! Eski çıktımıza geri döndük. Ancak unutmayalım ki synchronized Java’nın bize sağladığı bir imkan onun için Wikipedia Singleton pattern başlığında gördüğüm yöntemle devam edeceğiz. Bu yöntemde ilk koddaki gibi ilkleme sınıf yükleme esnasında ancak yardımcı başka bir sınıfın yüklenmesinde gerçekleşecek. (Kod 6)

public class Singleton {
	private static class SingletonHolder {
		// İlklemeyi ilk örnekteki gibi sınıf yüklemesi esnasına taşıyacağız.
		// Ancak bu sefer ilklemeyi Singleton değil yardımcı başka bir sınıf
		// gerçekleştirecek.
		private final static Singleton INSTANCE = new Singleton();
	}

	public static Singleton getInstance() {
		// Bu kullanım SingletonHolder sınıfının yüklenmesini dolayısıyla
		// Singleton nesnesinin ilklenmesini tetikleyecek.
		return SingletonHolder.INSTANCE;
	}

	private Singleton() {
		// Constructor private tanımlansın ki dışarıdan erişilemesin.
		System.out.println("constructor");

		// Constructor 100 ms. bekleme gibi bir "iş" yapsın.
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Yayınlandı gezegen, java, linux, yazılım

16 Nisan 2009

Posted In: Gezegen, java, linux, yazılım

Twitter Auto Publish Powered By : XYZScripts.com