2015年4月13日 星期一

[JAVA] java memory mode with "volatile" & "synchronized"

As a matter of fact, the Java memory model is such that a modification
to a variable in one thread may not immediately be visible to other threads. Actually, it
may never be visible. Consider the code in Listing 5–11: if one thread calls
MyClass.loop(), and at some point in the future another thread calls
Myclass.setValue(100), the first thread may still not terminate; may carry on looping
forever and always print out a value other than 100, simply because of the Java
language’s memory model.
Listing 5–11. Java Memory Model Impact
public class MyClass {
     private static final String TAG = "MyClass";
     private static int mValue = 0;
     public static void setValue(int n) {
          mValue = n;
     }
     public static void loop () {
          while (mValue != 100) {
               try {
                    Log.i(TAG, “Value is ” + mValue);
                    Thread.sleep(1000);
               } catch (Exception e) {
                    // ignored
               }
          }
     }
}
You have two options to fix that:
Use the synchronized keyword, as shown in Listing 5–12.
Use the volatile keyword, as shown in Listing 5–13.
Listing 5–12. Adding the Synchronized Keyword
public class MyClass {
     private static final String TAG = "MyClass";
     private static int mValue = 0;
     public static synchronized void setValue(int n) {
          mValue = n;
     }
     public static synchronized int getValue() {
          return mValue;
     }
     public static void loop () {
          int value;
          while ((value = getValue()) != 100) {
          try {
               Log.i(TAG, “Value is ” + value);
               Thread.sleep(1000);
               } catch (Exception e) {
              // ignored
               }
          }
     }
}

Listing 5–13. Adding the Volatile Keyword
public class MyClass {
     private static final String TAG = "MyClass";
     private static volatile int mValue = 0; // we add the volatile keyword and remove
     the synchronize keyword
     public static void setValue(int n) {
          mValue = n; // you’d still have to use synchronized if that statement were mValue += n (not atomic)
     }
     public static void loop () {
          while (mValue != 100) {
               try {
               Log.i(TAG, “Value is ” + mValue);
               Thread.sleep(1000);
               } catch (Exception e) {
              // ignored
               }
          }
     }
}

2015年4月12日 星期日

[Android] Handlers and Loopers

Android defines two classes in the android.os package that will often be the
cornerstones of the interthread communication in your multithreaded applications:
Handler
Looper
While creating an AsyncTask object hides the Handler and Looper details from you, in
some cases you need to use handlers and loopers explicitly, for example when you need
to post a Runnable to a thread other than the main thread.

you use a
Handler object to post a Runnable in a Looper’s message queue. Your application’s main
thread already has a message queue, so you don’t have to create one explicitly.
However, the threads you create do not come automatically with a message queue and
message loop, so you would have to create one yourself if needed. Listing 5-8  shows
how you can create a thread with a Looper.
Listing 5–8
public class MyThread extends Thread {
     private static final String TAG = “MyThread”;
     private Handler mHandler;
     public MyThread(String name) {
          super(name);
     }
     public Handler getHandler() {
          return mHandler;
     }
     @Override
     public void run() {
          Looper.prepare(); // binds a looper to this thread
          mHandler = new Handler() {
          @Override
          public void handleMessage(Message msg) {
               switch (msg.what) {
               // process messages here
               }
          }
     };
     // the handler is bound to this thread’s looper
     Looper.loop(); // don’t forget to call loop() to start the message loop
      // loop() won’t return until the loop is stopped (e.g., when Looper.quit() is called)
     }
}
Android provides an easier way to work with looper threads with the HandlerThread
class, which also makes it easier to avoid the potential race condition mentioned in
Listing 5–8, where getHandler() may still return null even after the thread has been
started. Listing 5–9 shows how to use the HandlerThread class.
Listing 5–9. Using the HandlerThread Class
     public class MyHandlerThread extends HandlerThread {
     private static final String TAG = "MyHandlerThread";
     private Handler mHandler;
     public MyHandlerThread(String name) {
          super(name);
     }
     public Handler getHandler() {
          return mHandler;
     }
@Override
     public void start() {
          super.start();
          Looper looper = getLooper(); // will block until thread’s Looper object is initialized
          mHandler = new Handler(looper) {
               @Override
                    public void handleMessage(Message msg) {
                         switch (msg.what) {
                         // process messages here
                    }
               }
          };
     }

}

2015年4月7日 星期二

[Android][Java] Java define 4 reference type

Strong
Soft
Weak
Phantom

it is important to avoid memory leak
Android’s LruCache uses strong references

2015年3月26日 星期四

[Design Partern] Strategy pattern case 1: Android load NDK library

在 Android 的開發中使用 NDK 最佳化的時候,可能會因為平台的差異,導致 native code 無法執行,這時候必須提供 Java 版本的 solution。

Design Pattern 裡面有一個Strategy pattern,他的特性如下:
In computer programming, the strategy pattern (also known as the policy pattern) is a software design pattern that enables an algorithm's behavior to be selected at runtime. The strategy pattern

1. defines a family of algorithms,
2. encapsulates each algorithm, and
3. makes the algorithms interchangeable within that family.

載入 native library 的時機點也是在 runtime,剛好符合 Startegy pattern 的 case:
例子如下:

2015年3月20日 星期五

[Performance] Fibonacci演算法探討演算法最佳解



這是基本的解法,但是會 overflow,遞迴會造成 stack 爆掉, performance很差

Fibonacci的演算公式,可減少程式的複雜度





接近完美的解法,倒入 cache 機制和 Android 特有的 SparseArray:





















2014年12月29日 星期一

[Android] 可以 count Jar 檔案的 method 數量的 script

dx --dex --output=temp.dex $1
cat temp.dex | head -c 92 | tail -c 4 | hexdump -e '1/4 "%d\n"'
rm temp.dex

dx 要用
/home/charles_lo/Program/adt-bundle-linux-x86_64-20140702/sdk/build-tools/21.1.1
不要用 apt-get 去安裝
實測效果