ConditionVariable在Android應用開發中的用法

首先來看下ConditionVariable類的定義:

C:\Program Files\Android\android-sdk\platforms\android-21\android.jar


package android.os;

public class ConditionVariable
{
    private volatile boolean mCondition;


    /**
     * Create the ConditionVariable in the default closed state.
     */
    public ConditionVariable()
    {
        mCondition = false;
    }


    /**
     * Create the ConditionVariable with the given state.
     * Pass true for opened and false for closed.
     */
    public ConditionVariable(boolean state)
    {
        mCondition = state;
    }


    /**
     * Open the condition, and release all threads that are blocked.
     * Any threads that later approach block() will not block unless close()
     * is called.
     */
    public void open()
    {
        synchronized (this) {
            boolean old = mCondition;
            mCondition = true;
            if (!old) {
                this.notifyAll();
            }
        }
    }


    /**
     * Reset the condition to the closed state.
     * Any threads that call block() will block until someone calls open.
     */
    public void close()
    {
        synchronized (this) {
            mCondition = false;
        }
    }


    /**
     * Block the current thread until the condition is opened.
     * If the condition is already opened, return immediately.
     */
    public void block()
    {
        synchronized (this) {
            while (!mCondition) {
                try {
                    this.wait();
                }
                catch (InterruptedException e) {
                }
            }
        }
    }


    /**
     * Block the current thread until the condition is opened or until
     * timeout milliseconds have passed.
     * @param timeout the minimum time to wait in milliseconds.
     *
     * @return true if the condition was opened, false if the call returns
     * because of the timeout.
     */
    public boolean block(long timeout)
    {
        // Object.wait(0) means wait forever, to mimic this, we just
        // call the other block() method in that case.  It simplifies
        // this code for the common case.
        if (timeout != 0) {
            synchronized (this) {
                long now = System.currentTimeMillis();
                long end = now + timeout;
                while (!mCondition && now < end) {
                    try {
                        this.wait(end-now);
                    }
                    catch (InterruptedException e) {
                    }
                    now = System.currentTimeMillis();
                }
                return mCondition;
            }
        } else {
            this.block();
            return true;
        }
    }
}

這裏詳述了ConditionVariable類的實現過程及其內部函數。該類內部定義了一個volatile 類型的 mCondition 變量,通過控制這個變量的值,來實現對wait()函數的調用,達到控制線程是否阻塞的目的。

這裏寫了一個簡單的實例來模擬整個控制過程

public class MainActivity extends Activity implements OnClickListener {
    private Button btn_output;
    private TextView textView;
    private MyHandler mHandler;
    private boolean isStart;
    private String str = "";
    private ConditionVariable mConditionVariable;
    private final int REFRESHTEXT = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_output = (Button) findViewById(R.id.btn);
        btn_output.setOnClickListener(this);
        textView = (TextView) findViewById(R.id.txt);
        mHandler = new MyHandler();
        mConditionVariable = new ConditionVariable();
        isStart = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                while(isStart) {
                    //延時等待3秒
                    mConditionVariable.block(3000);
                    //如果是點擊了按鈕,則先將條件重置,否則block會失效
                    mConditionVariable.close();
                    //線程喚醒後通知主線程更新TextView的文本
                    mHandler.sendEmptyMessage(REFRESHTEXT);
                }
            }
        }).start();
    }
   
    private class MyHandler extends Handler {
        @Override
public void handleMessage(Message msg) {
            switch(msg.what) {
            case REFRESHTEXT:

textView.setTextSize(20.0f);
                textView.setText(str += 's');
                break;
            }
        }
    }
       
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        mConditionVariable.open();
    }
   
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        isStart = false;
    }
}


運行該實例,你會發現按鈕旁邊的字符串會由hello world變爲S,並且S會一直增加,每隔3秒增加一個S;

如果你有手動點擊按鈕的話,就會直接增加一個S,而不用等待3秒;

這個案例是從別處借鑑過來的,思路不錯,就實驗了一把,並且效果也不錯。

但這個代碼有一處不嚴謹的地方就是在退出該Activity時,並未將mConditionVariable對象重置,建議在onDestroy()函數中增加mConditionVariable.close()調用會顯得更爲嚴謹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章