Condition

  Condition用来显式的定义条件变量,必须与显式锁配套使用。一个显式锁可以配套多个Condition,通过显式锁的newCondition方法得到,条件的判断和Condition的阻塞、通知必须在显式锁的保护下进行。下面看一个通过Condition实现信号量流控的例子(原例子在http://www.cnblogs.com/wuxun1997/p/6822868.html第2点):

package com.wulinfeng.concurrent;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SemaphoreOnLock {
    private final Lock lock = new ReentrantLock();
    private final Condition permitAvailable = lock.newCondition(); // 条件变量
    private int permits;
    private AtomicInteger concurrent = new AtomicInteger(0);
    private AtomicInteger count = new AtomicInteger(0);

    public SemaphoreOnLock(int capacity) {
        lock.lock();
        try {
            this.permits = capacity;
        } finally {
            lock.unlock();
        }
    }

    public void acquire() throws InterruptedException {
        lock.lock();
        try {
            while (permits <= 0) {  // 具体条件
                permitAvailable.await();  // 阻塞线程
            }
            --permits;
        } finally {
            lock.unlock();
        }
    }

    public void release() {
        lock.lock();
        try {
            ++permits;
            permitAvailable.signal(); // 唤醒阻塞线程
        } finally {
            lock.unlock();
        }
    }

    public void service(int request, SemaphoreOnLock sem) throws InterruptedException {

        // 获取信号量,并发数+1
        sem.acquire();
        concurrent.incrementAndGet();

        // 总数+1
        count.incrementAndGet();

        try {
            System.out.printf("request is %d, concurrent is %d, total is %d
", request, concurrent.get(), count.get());
        } finally {
            sem.release(); // 释放信号量
            concurrent.decrementAndGet();  // 并发数-1
        }
    }

    public static void main(String[] args) {
        final SemaphoreOnLock sem = new SemaphoreOnLock(10);
        final ExecutorService es = Executors.newFixedThreadPool(20);
        final Random r = new Random();

        try {
            for (int i = 0; i < 50; i++) {
                es.execute(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            sem.service(r.nextInt(), sem);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        } finally {
            es.shutdown();
        }
    }
}

  运行结果:

request is -1778951338, concurrent is 1, total is 1
request is 1075066906, concurrent is 10, total is 10
request is -200837414, concurrent is 9, total is 9
request is -1639190194, concurrent is 10, total is 13
request is 71037621, concurrent is 10, total is 14
request is -585938121, concurrent is 10, total is 15
request is -1900131855, concurrent is 10, total is 16
request is -1116159838, concurrent is 8, total is 8
request is 1258746809, concurrent is 10, total is 18
request is 706480516, concurrent is 10, total is 19
request is 1434452493, concurrent is 10, total is 20
request is -729026036, concurrent is 10, total is 21
request is -779583500, concurrent is 10, total is 22
request is -549833234, concurrent is 10, total is 23
request is 1485006269, concurrent is 10, total is 24
request is 1970523873, concurrent is 10, total is 25
request is 869293408, concurrent is 10, total is 26
request is -1803861924, concurrent is 10, total is 27
request is 1638663365, concurrent is 10, total is 28
request is 1696301910, concurrent is 10, total is 29
request is 399361261, concurrent is 10, total is 30
request is 578417246, concurrent is 10, total is 31
request is -1116143520, concurrent is 10, total is 32
request is -1664615245, concurrent is 10, total is 33
request is 1562712140, concurrent is 10, total is 34
request is -1118179524, concurrent is 7, total is 7
request is 1917249326, concurrent is 10, total is 36
request is -838893383, concurrent is 10, total is 37
request is 1699389705, concurrent is 10, total is 38
request is -994637321, concurrent is 10, total is 39
request is -1774265235, concurrent is 10, total is 40
request is -1954116413, concurrent is 6, total is 6
request is -1406911710, concurrent is 5, total is 5
request is 1128024304, concurrent is 9, total is 42
request is 992412262, concurrent is 4, total is 4
request is -231446201, concurrent is 8, total is 43
request is 2012613692, concurrent is 8, total is 44
request is 1376746080, concurrent is 8, total is 45
request is 2140793768, concurrent is 8, total is 46
request is 2026689142, concurrent is 3, total is 3
request is -279664490, concurrent is 9, total is 49
request is 983193837, concurrent is 2, total is 2
request is -837354594, concurrent is 8, total is 50
request is -294562086, concurrent is 10, total is 48
request is -402585996, concurrent is 9, total is 47
request is 1943809799, concurrent is 10, total is 41
request is 485819205, concurrent is 10, total is 35
request is 835221789, concurrent is 10, total is 17
request is 2089139150, concurrent is 11, total is 12
request is 2097235027, concurrent is 10, total is 11
原文地址:https://www.cnblogs.com/wuxun1997/p/6980316.html