Condition

Posted 不想下火车的人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Condition相关的知识,希望对你有一定的参考价值。

  Condition用来显式的定义条件变量,必须与显式锁(Lock的实现类)配套使用。一个显式锁可以配套多个Condition,通过显式锁的newCondition方法得到,条件的判断和Condition的阻塞、通知必须在显式锁的保护下进行。

  条件变量对象Condition的await、signal、signalAll跟Object的wait、notify、notifyAll方法一样,都是成对出现的。不同之处有三:

  1、从粒度上说:Condition服务的是锁,锁服务于线程;而Object结合内部锁Synchronized直接用来服务线程通信;

  2、从形式上说:Condition的await通常是用while(条件){锁.await()}的样子出现;而Object.wait()往往在同步代码块或同步方法中出现;

  3、从数量上说:一个锁可拥有多个Condition,自然也就可以有多个await、signal和signalAll了;而同一个对象Object中只能有一个wait、notify、notifyAll。

  下面看一个通过Condition实现信号量流控的例子(原例子在信号量Semaphore使用实例的第2点):

package com.wlf.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\\n", 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

 

以上是关于Condition的主要内容,如果未能解决你的问题,请参考以下文章

java线程condition

Java ReEntrantLock 之 Condition条件(Java代码实战-002)

Condition源码分析

if(!!condition) 和 if(condition) 有啥区别

[C]if (CONDITION)语句中CONDITION的情况

VBA 使用“或”条件执行直到循环