Thursday, October 18, 2007

Sınır Ötesi Operasyon

Son günlerde gündemi meşgul eden en önemli haber TBMM'nin hükümete sınır ötesi harekat için yetki vermesi. Sınır ötesi operasyon gerekli mi gereksiz mi tartışmaları sürerken gerçekler gözden kaçırılıyor. TBMM'de bizi temsil eden millet vekilleri arasında PKK'yı bölücü teror örgütü olarak tanımayan millet vekilleri var. Durum böyleyken bizim operasyonu sınır ötesinde değil öncelikle kendi millet meclisimiz içinde yapmamız gerekir. Türkiye Cumhuriyeti vatandaşlarını, devletin bölünmez bütünlüğüne zarar vermek için acımasızca öldüren, binlerce çocuğu anasız babasız bırakan eli kanlı bu terör örgütünü "TERÖR ÖRGÜTÜ" olarak adlandıramayan millet vekilleri meclis çatısı altında nasıl barınır aklım almıyor. Demokrasi böyle birşey olsa gerek.

Blogged with Flock

Thursday, October 4, 2007

Volatile Variables In JAVA



Java Memory model defines the possible rules for threads and the expected behavior of multi-threaded programs so that programmers can design their programs accordingly. JSR-133 describes the semantics of threads, locks, volatile variables and data races.

Volatile variables are treated different from other variables. When you mark a variable as volatile, this warns the compiler to get fresh copies of the variable rather than caching the variable in the registers.

Volatile variables can be used to store shared variables at a lower cost than that of synchronization, but they have limitations. While writes to volatile variables are guaranteed to be immediately visible to other threads (because JVM does not allow threads to cache volatile variables), there is no way to render a read-modify-write sequence of operations atomic, meaning, for example, that a volatile variable cannot be used to reliably implement a mutex (mutual exclusion lock) or a counter.

Let's demonstrate this with a counter example. In the example a volatile counter variable will be incremented by multiple threads simultaneously. Below is the main class that holds the volatile variable and starts the threads.



01 package com.oksijen.concurrency.volatiletest;
02 
03 import java.util.concurrent.CountDownLatch;
04 
05 public class VolatileTest {
06 
07     public static volatile long counter = 0L;
08     private CountDownLatch allThreadsAreDone = null;;
09     private CountDownLatch allThreadsAreReady = null;
10     
11     public static void main(String[] args) {
12         VolatileTest test = new VolatileTest();
13         int numberOfThreads = 10;
14         int incrementCountPerThread = 10000;
15         CountDownLatch countDownLatch1 = new CountDownLatch(numberOfThreads);
16         test.setAllThreadsAreDone(countDownLatch1);
17         CountDownLatch countDownLatch2 = new CountDownLatch(numberOfThreads);
18         test.setAllThreadsAreReady(countDownLatch2);
19         test.start(numberOfThreads, incrementCountPerThread);
20         test.waitForThreadTermination();
21         System.out.println("Expected counter value : " + numberOfThreads * incrementCountPerThread);
22         System.out.println("Result : " + VolatileTest.counter);
23     }
24     /**
25      * prints out result after all threads finish execution
26      */
27     private void waitForThreadTermination() {
28         try {
29             System.out.println(Thread.currentThread().getName() " waiting for other threads...");
30             this.allThreadsAreDone.await();
31             System.out.println(Thread.currentThread().getName() " threads finished their work.");
32         catch (InterruptedException e) {
33             e.printStackTrace();
34         }
35     }
36     /**
37      @param numberOfThreads
38      @param incrementCount
39      */
40     private void start(int numberOfThreads, int incrementCount) {
41         for (int i=0; i<numberOfThreads; i++) {
42             MyThread thread = new MyThread(incrementCount, this.allThreadsAreDone, this.allThreadsAreReady);
43             thread.setName("MyThread_"+i);
44             thread.start();
45             this.allThreadsAreReady.countDown();
46         }
47     }
48     /**
49      * synchronized counter increment.
50      */
51     public static synchronized void incrementCounter(){
52         counter++;
53     }
54     /**
55      @param allThreadsAreDone the allThreadsAreDone to set
56      */
57     public void setAllThreadsAreDone(CountDownLatch allThreadsAreDone) {
58         this.allThreadsAreDone = allThreadsAreDone;
59     }
60     /**
61      @param allThreadsAreReady the allThreadsAreReady to set
62      */
63     public void setAllThreadsAreReady(CountDownLatch allThreadsAreReady) {
64         this.allThreadsAreReady = allThreadsAreReady;
65     }
66     
67 }


Here is our example thread source code:



01 package com.oksijen.concurrency.volatiletest;
02 
03 import java.util.concurrent.CountDownLatch;
04 
05 public class MyThread extends Thread {
06 
07     private int incrementCount = 0;    
08     private CountDownLatch done = null;
09     private CountDownLatch ready = null;
10     
11     public MyThread(int incrementCount, CountDownLatch done, CountDownLatch ready){
12         this.incrementCount = incrementCount;
13         this.done = done;
14         this.ready = ready;
15     }
16     
17     public void run() {
18         try {
19             System.out.println(Thread.currentThread().getName() " started.");
20             this.ready.await();
21             for (int i=0; i<this.incrementCount; i++) {
22                 VolatileTest.counter++;
23                 /*
24                  * if we want to increment the counter synchronously we use the
25                  * sync incrementCounter() method.
26                  
27                  * VolatileTest.incrementCounter();
28                  */  
29             }
30             System.out.println(Thread.currentThread().getName() " ended.");
31             this.done.countDown();            
32         catch (InterruptedException e) {
33             e.printStackTrace();
34         }
35     }
36 }


I used jdk1.5.0_12 to run this application. I used 10 threads, each increments the variable 10000 times. The result is as expected. Volatile keyword does not guarantie mutual exclusion. Here is the result:

Expected counter value : 100000
Result : 85751
As a result: Volatile variables are best for use when there is only one thread that makes writes (updates volatile variable) and N threads that make reads. Reader threads get the most recent value of the volatile parameter when they perform a read.