İki haftadır Hakan Güler'in "throttling" olarak anlattığı yapıyı kullanarak bir test uygulaması yazıyorum. Bu yapı senkronizasyonun gerekli olduğu yerlerde oldukça basit ve yeterli bir mekanizma kurmanıza izin veriyor.
Bir benzetme yapmak gerekirse: Bir posta işletmesinde mektupları gidecekleri şehire göre ayıran bir memur düşünelim. Gelen mektuplar bu postacıya direkt verilmemeli bir kutuya atılmalıdır. Memur bu kutudan bir mektup alarak, ilgili şehrin kutusuna yerleştirir. Eğer bu işi yapan birden fazla memur olursa, her memurun kendisine ait bir kutusu olmalıdır. Her memur sadece tek bir kutudan sorumlu olduğu için, hata yapma ve diğer memurlarla çakışma olasılığı ortadan kalkar.
Bunu gerçekleştirmek için, öncelikle bir kuyruk değişkeni tanımlayıp, ana döngünüzün (posta memuru) işlemesini istediğiniz her türlü mesajı bu kuyruğa (kutuya) atmanız gerekiyor. Döngü her seferinde bu kuyruktaki ilk mesajı alıp, işleyip ve bir sonraki mesaja geçmeli. Örnek bir kod vermek gerekirse:
public void run() {
while (null != (message = getMessage())) {
// do actions
}
}
public void putMessage(Object message) {
synchronized (messageQueue) {
if (null != message) {
messageQueue.addLast(message);
}
messageQueue.notify();
}
}
public Object getMessage() {
synchronized (messageQueue) {
while (0 == messageQueue.size()) {
try {
messageQueue.wait();
} catch (Exception e) {}
}
return messageQueue.removeFirst();
}
}
Bu yöntemin hızlı çalışması için döngünün hızlı çalışması gerekir. Yani döngü içerisinde dosyaya yazma gibi işlemler yapılırsa bu yöntemin hızlı çalışmasına engel olacaktır.