一手遮天 Android - 锁和并发处理: Lock 演示 Condition 的 await() signal() signalAll() 的使用

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

一手遮天 Android - 锁和并发处理: Lock 演示 Condition 的 await() signal() signalAll() 的使用

示例如下:

/concurrent/LockDemo3.java

/**
 * Lock(演示 Condition 的 await() signal() signalAll() 的使用)
 *
 * Lock 是一个接口,ReentrantLock 实现了这个接口
 *     newCondition() - 创建一个新的 Condition 对象
 *
 * Condition
 *     await() - 阻塞当前 Condition 的线程
 *     signal() - 当前 Condition 的某一个被 await() 的线程被唤醒(具体是哪个线程会被唤醒是由系统决定的,无法预知)
 *     signalAll() - 当前 Condition 的所有被 await() 的线程都会被唤醒
 *
 *
 *  注:关于 Object 的 wait() notify() notifyAll() 的说明,请参见“async.ThreadDemo2”
 *
 *
 *  本示例通过生产者/消费者模型来演示 await() signal() signalAll() 的使用
 *  关于本例中的生产者/消费者模型,说明如下:
 *  1、Pool 是仓库,最多保存 10 件商品
 *  2、Producer 是生产者(一共有 5 个),如果仓库中的商品小于 10 件的话,则找一个生产者生产 1 件商品放到仓库
 *  3、Consumer 是消费者(一共有 5 个),如果仓库中的商品大于 0 件的话,则找一个消费者从仓库拿走 1 件商品
 */

package com.webabcd.androiddemo.concurrent;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.webabcd.androiddemo.R;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockDemo3 extends AppCompatActivity {

    private final String LOG_TAG = "LockDemo3";

    private Lock _lock = new ReentrantLock();
    private Condition _producerCondition = _lock.newCondition();
    private Condition _consumerCondition = _lock.newCondition();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_concurrent_lockdemo3);

        sample();
    }

    private void sample() {
        Pool pool = new Pool();

        for (int i = 0; i < 5; i++) {
            Producer producer = new Producer(pool);
            producer.setName("producer" + i);
            producer.start();
        }

        for (int i = 0; i < 5; i++) {
            Consumer consumer = new Consumer(pool);
            consumer.setName("consumer" + i);
            consumer.start();
        }
    }

    // 仓库
    class Pool {
        private List<Integer> list = new LinkedList<Integer>();
        private int max = 10;
        private int serialNo = 0;

        public int add() {
            _lock.lock();
            try {
                String threadName = Thread.currentThread().getName();
                while (list.size() >= max) {
                    try {
                        // 阻塞当前 _producerCondition 的线程
                        _producerCondition.await();
                    } catch (Exception e) {

                    }
                }

                serialNo++;
                list.add(new Integer(serialNo));
                Log.d(LOG_TAG, String.format("%s, %d, %d", threadName, list.size(), serialNo));

                // 唤醒一个 _consumerCondition 的线程
                _consumerCondition.signal();

                return serialNo;
            } finally {
                _lock.unlock();
            }
        }

        public int remove() {
            _lock.lock();
            try {
                String threadName = Thread.currentThread().getName();
                while (list.size() == 0) {
                    try {
                        // 阻塞当前 _consumerCondition 的线程
                        _consumerCondition.await();
                    } catch (Exception e) {

                    }
                }

                int serialNo = list.remove(0);
                Log.d(LOG_TAG, String.format("%s, %d, %d", threadName, list.size(), serialNo));

                // 唤醒一个 _producerCondition 的线程
                _producerCondition.signal();

                return serialNo;
            } finally {
                _lock.unlock();
            }
        }
    }

    // 生产者
    class Producer extends Thread {
        private Pool pool;

        public Producer(Pool pool) {
            this.pool = pool;
        }

        public void run() {
            while (true) {
                int serialNo = pool.add();
            }
        }

    }

    // 消费者
    class Consumer extends Thread {
        private Pool pool;

        public Consumer(Pool pool) {
            this.pool = pool;
        }

        public void run() {
            while (true) {
                int serialNo = pool.remove();
            }
        }
    }
}

/layout/activity_concurrent_lockdemo3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="详见 java 代码" />

</LinearLayout>

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

posted @ 2021-06-02 09:49  webabcd  阅读(276)  评论(0编辑  收藏  举报