码迷,mamicode.com
首页 > 其他好文 > 详细

信号量

时间:2017-05-06 22:56:12      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:es.exe   service   lin   pac   cap   row   package   gen   thread   

  信号量就好像线程池,只不过这池子里放的是信号。当我们要控制对资源的访问次数或者操作次数的时,需要先从池子里取出一个信号,访问或者操作结束后,再把信号放回池子里。下面举例分别说明对资源(一个List)和操作(一个service方法)的控制实现,使用线程池来调度多线程:

  1、有界List实现:

package com.wulinfeng.concurrent;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Semaphore;

public class BoundedList<T> {

    private final Semaphore sem;
    private List<T> list;

    public BoundedList(int capacity) {
        this.sem = new Semaphore(capacity);

        // 包装一个线程安全的列表
        this.list = Collections.synchronizedList(new LinkedList<T>());
    }

    public boolean add(T t) throws InterruptedException {
        // 可用信号已用光表示到达列表边界,再插入则报错,
        if (sem.availablePermits() < 1) {
            throw new ArrayIndexOutOfBoundsException();
        }

        // 申请信号
        sem.acquire();

        boolean isAdded = false;
        try {
            isAdded = list.add(t);
            return isAdded;
        } finally {
            // 插入失败则释放信号
            if (!isAdded) {
                sem.release();
            }
        }
    }

    public boolean remove(T t) {
        boolean isRemoved = false;

        try {
            isRemoved = list.remove(t);
            return isRemoved;
        } finally {
            // 成功删除则释放信号
            if (isRemoved) {
                sem.release();
            }
        }
    }

    public T get(int index) {
        return list.get(index);
    }

    public static void main(String[] args) throws InterruptedException {
        BoundedList<String> bl = new BoundedList<String>(2);
        bl.add("hello");
        bl.add("world");
        System.out.printf("%s,%s!\n", bl.get(0), bl.get(1));

        // 越界了
        bl.add("outIndex");
    }
}

  运行结果:

hello,world!
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
    at com.wulinfeng.concurrent.BoundedList.add(BoundedList.java:23)
    at com.wulinfeng.concurrent.BoundedList.main(BoundedList.java:66)

  2、流控实现:

package com.wulinfeng.concurrent;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

public class BoundedRequest {
    private final Semaphore sem;
    private AtomicInteger concurrent = new AtomicInteger(0);
    private AtomicInteger count = new AtomicInteger(0);

    public BoundedRequest(int capacity) {
        this.sem = new Semaphore(capacity, true);
    }

    public void service(int request) throws InterruptedException {

        // 业务开始前,申请流量,计算并发数,+1
        sem.acquire();
        concurrent.incrementAndGet();

        // 统计请求数
        count.incrementAndGet();

        try {
            System.out.printf("request is %d, concurrent is %d, total is %d\n", request, concurrent.get(), count.get());
        } finally {
            // 业务结束后,释放流量,计算并发数,-1
            sem.release();
            concurrent.decrementAndGet();
        }
    }

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

        // 并发100个请求调用service,但service只能容许10个并发
        for (int i = 0; i < 100; i++) {
            es.execute(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        br.service(r.nextInt());
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

  运行结果:

request is -1297233033, concurrent is 1, total is 1
request is -6281068, concurrent is 10, total is 10
request is -678801947, concurrent is 9, total is 11
request is -590548811, concurrent is 9, total is 12
request is 801707224, concurrent is 9, total is 9
request is -305017415, concurrent is 8, total is 8
request is 48043883, concurrent is 7, total is 7
request is 1003556449, concurrent is 6, total is 13
request is -11481028, concurrent is 6, total is 6
request is 2130603109, concurrent is 5, total is 5
request is 1889832541, concurrent is 4, total is 4
request is -697338282, concurrent is 3, total is 3
request is -1137220526, concurrent is 5, total is 14
request is -2087879652, concurrent is 2, total is 15
request is -565819593, concurrent is 2, total is 16
request is -1640650992, concurrent is 2, total is 17
request is 1667344967, concurrent is 2, total is 18
request is -1941976398, concurrent is 2, total is 19
request is -40077468, concurrent is 2, total is 20
request is 2001752857, concurrent is 2, total is 21
request is -468461925, concurrent is 4, total is 24
request is 2138430884, concurrent is 7, total is 28
request is 1672948777, concurrent is 10, total is 32
request is -788356423, concurrent is 10, total is 33
request is 134291469, concurrent is 10, total is 34
request is 1947765688, concurrent is 2, total is 2
request is -1287504760, concurrent is 10, total is 31
request is -864279896, concurrent is 9, total is 30
request is -595059133, concurrent is 8, total is 29
request is -1715075903, concurrent is 7, total is 27
request is 1086389923, concurrent is 6, total is 26
request is 773899443, concurrent is 5, total is 25
request is 1663655125, concurrent is 4, total is 23
request is 1451369308, concurrent is 3, total is 22
request is 268986133, concurrent is 1, total is 35
request is 1714802532, concurrent is 1, total is 36
request is -509507526, concurrent is 1, total is 37
request is -1805960875, concurrent is 1, total is 38
request is 99786093, concurrent is 1, total is 39
request is -603406311, concurrent is 1, total is 40
request is 335335679, concurrent is 1, total is 41
request is 442078207, concurrent is 1, total is 42
request is -629830600, concurrent is 2, total is 43
request is 1324665799, concurrent is 1, total is 44
request is -957395332, concurrent is 1, total is 45
request is 1542818164, concurrent is 10, total is 54
request is -202910677, concurrent is 9, total is 53
request is -1842161758, concurrent is 8, total is 52
request is -2063848777, concurrent is 7, total is 51
request is 1355626887, concurrent is 6, total is 50
request is -2089995580, concurrent is 5, total is 49
request is -1523950311, concurrent is 4, total is 48
request is -1235409536, concurrent is 3, total is 47
request is 396289750, concurrent is 2, total is 46
request is -12856578, concurrent is 1, total is 55
request is -1700037942, concurrent is 1, total is 56
request is 867665708, concurrent is 1, total is 57
request is 547121095, concurrent is 1, total is 58
request is 1711870372, concurrent is 1, total is 59
request is 467075074, concurrent is 1, total is 60
request is -869354867, concurrent is 1, total is 61
request is -2044599095, concurrent is 1, total is 62
request is -344899348, concurrent is 1, total is 63
request is 854485055, concurrent is 1, total is 64
request is -913866303, concurrent is 1, total is 65
request is 392977523, concurrent is 1, total is 66
request is -963103469, concurrent is 1, total is 67
request is 1370270884, concurrent is 1, total is 68
request is 2031081868, concurrent is 1, total is 69
request is 949680197, concurrent is 1, total is 70
request is -120718448, concurrent is 1, total is 71
request is -48740735, concurrent is 1, total is 72
request is -1576176915, concurrent is 1, total is 73
request is -763495850, concurrent is 1, total is 74
request is -240465251, concurrent is 1, total is 75
request is 206094972, concurrent is 1, total is 76
request is -1911668681, concurrent is 1, total is 77
request is -1931467348, concurrent is 1, total is 78
request is 1501291766, concurrent is 1, total is 79
request is -1642736883, concurrent is 1, total is 80
request is -1980268416, concurrent is 1, total is 81
request is -443689011, concurrent is 1, total is 82
request is 750024160, concurrent is 2, total is 83
request is 2038470191, concurrent is 1, total is 84
request is -513268417, concurrent is 1, total is 85
request is -1779607571, concurrent is 10, total is 94
request is 1806884731, concurrent is 9, total is 93
request is -1159942504, concurrent is 8, total is 92
request is 2060551420, concurrent is 7, total is 91
request is 1597480266, concurrent is 6, total is 90
request is -936808912, concurrent is 5, total is 89
request is 746521171, concurrent is 4, total is 88
request is 482453868, concurrent is 3, total is 87
request is -1950636139, concurrent is 2, total is 86
request is 739263494, concurrent is 1, total is 95
request is 979593785, concurrent is 1, total is 96
request is 527758868, concurrent is 1, total is 97
request is -1175014446, concurrent is 1, total is 98
request is -1260897001, concurrent is 1, total is 99
request is 900814663, concurrent is 1, total is 100

 

信号量

标签:es.exe   service   lin   pac   cap   row   package   gen   thread   

原文地址:http://www.cnblogs.com/wuxun1997/p/6818748.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!