Android中Semaphore信号量的使用与陷阱

需积分: 12 2 下载量 145 浏览量 更新于2024-09-11 收藏 188KB PDF 举报
_semaphore 使用详解 semaphore 是 Android 编程中的一种同步机制,它可以控制对共享资源的访问。 semaphore 的使用可以分为两种情况:初始值为零和初始值不为零。本文主要介绍初始值为零的情况,并对 semaphore 的使用进行详细的解释。 Semaphore 的创建 在 Android 中,semaphore 可以通过 newSemaphore() 方法创建,例如:`index = new Semaphore(1);`。这句话创建了一个初始值为 1 的 semaphore 类型信号量。注意,这里的初始值 1 并不是最大值,而是 semaphore 的初始计数器值。 Semaphore 的使用 semaphore 的使用可以分为两步:release() 和 acquire()。release() 方法可以增加 semaphore 的计数器值,例如:`index.release();`。这句话执行后,semaphore 的计数器值将增加 1。acquire() 方法可以减少 semaphore 的计数器值,例如:`index.acquire();`。这句话执行后,semaphore 的计数器值将减少 1。 初始值为零的情况 如果 semaphore 的初始值为零,那么在使用之前必须先调用 release() 方法将计数器值加 1,例如:`mBuffer = new Semaphore(0);`。这句话创建了一个初始值为零的 semaphore,然后调用 `mBuffer.release();` 将计数器值加 1,最后才能使用 `mBuffer.acquire();` 申请信号量。 释放和申请的关系 在使用 semaphore 时,release 和 acquire 的次数是相关的。如果 semaphore 的初始值为 N,那么 acquire 的次数等于 release 的次数加 N。例如,如果 semaphore 的初始值为 1,那么 acquire 的次数等于 release 的次数加 1。 线程安全 semaphore 可以用于控制多线程的访问。例如,可以创建一个线程不断调用 release() 方法,使得 semaphore 的计数器值不断增加,而另一个线程不断调用 acquire() 方法,申请信号量。如果 semaphore 的计数器值为零,那么 acquire() 方法将阻塞到这里,直到 semaphore 的计数器值大于零。 代码实现 下面是一个使用 semaphore 控制多线程访问的示例代码: ```java public class MainActivity extends AppCompatActivity { private Semaphore mBufferRequested; private Button btn; private Test test; private Test2 test2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.button); // 按下按钮则启动两个新线程 btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 创建两个新线程 new Thread(new Runnable() { @Override public void run() { //不断调用 release() 方法,使得 semaphore 的计数器值不断增加 while (true) { mBufferRequested.release(); } } }).start(); new Thread(new Runnable() { @Override public void run() { // 不断调用 acquire() 方法,申请信号量 while (true) { mBufferRequested.acquire(); } } }).start(); } }); } } ``` 在上面的代码中,我们创建了两个线程,一个不断调用 release() 方法,使得 semaphore 的计数器值不断增加,而另一个不断调用 acquire() 方法,申请信号量。如果 semaphore 的计数器值为零,那么 acquire() 方法将阻塞到这里,直到 semaphore 的计数器值大于零。