简介
ConditionVariable 是一个实现多线程同步的类,是对 Object 方法中的 wait() 和 notify() 的封装。其提供了三个方法 open()、close()、block() 简化了多线程的同步操作。通过这个类我们可以非常便利的实现多线程的同步操作。
使用用法
先来看下它的使用方法,下面的例子是一个简化版的利用ConditionVariable实现的生产者消费者模式的例子:
import android.app.Activity;
import android.os.Bundle;
import android.os.ConditionVariable;
import android.util.Log;
public class TestActivity extends Activity {
private ConditionVariable mCondition;
private int mNumber;
private boolean isRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
mCondition = new ConditionVariable();
mNumber = 0;
isRunnable = true;
new Thread(new Runnable() {
@Override
public void run() {
while (isRunnable) {
//消费者
mCondition.close();
mCondition.block();
Log.d("TAG", "Customer:"+mNumber);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (isRunnable) {
//生产者
mNumber++;
Log.d("TAG", "Producter:"+mNumber);
mCondition.open();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
@Override
protected void onPause() {
super.onPause();
isRunnable = false;
}
}
通过例子我们知道 close() 和 block() 是一起配合使用的,其目的就是阻塞线程,等待 open() 的调用解除线程阻塞。block() 还有一个超时的方法,就是超过指定的时间就不再阻塞线程,这里就不多介绍了。ConditionVariable 的使用也是挺简单的,其源码实现也很简单。
源码实现
下面来看看它的源码实现:
public class ConditionVariable
{
private volatile boolean mCondition;
public ConditionVariable()
{
mCondition = false;
}
public ConditionVariable(boolean state)
{
mCondition = state;
}
public void open()
{
synchronized (this) {
boolean old = mCondition;
mCondition = true;
if (!old) {
this.notifyAll();
}
}
}
public void close()
{
synchronized (this) {
mCondition = false;
}
}
public void block()
{
synchronized (this) {
while (!mCondition) {
try {
this.wait();
}
catch (InterruptedException e) {
}
}
}
}
public boolean block(long timeout)
{
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;
}
}
}
通过其源码可以看出 close() 为什么要和 block() 配合使用了,如果在调用 open() 后,只使用 block() 不使用 close() 。block() 函数就不会起到阻塞线程的效果, 就是说它已经失去了同步线程的能力。所以,我们在多次使用 block() 函数实现线程阻塞的时候要和 close() 配套使用。
总结
ConditionVariable 在多线程同步上使用起来还是非常简便实用的。如果项目中需要用到多线程同步的可以使用这个类来实现相应的功能。