并发-Semaphore

Semaphore

  • 正常的锁在任何时刻都只允许一个任务访问一项资源,而计数信号量允许n个任务同时访问这个资源。还可以将信号量看作是在向外分发使用资源的“许可证”,尽管实际上没有使用任何许可证对象。
  • 对象池的概念,管理者数量有限的对象,当要使用对象时可以迁出它们,而在用户使用完毕时,可以将它们迁回。
package com21concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * Created by Panda on 2018/6/1.
 */
//对象池的封装
    //构造器使用newInstance()来把对象加载到池中。如果需要一个新的对象,那么可以调用checkOut()
    //并且在使用了之后,将其递交给checkIn()
public class Pool<T> {
    private int size;
    private List<T> items=new ArrayList<>();
    private volatile boolean[] checkedOut;
    private Semaphore available;

    public Pool(Class<T> classObject,int size) {
        this.size = size;
        //跟踪被迁出的对象,可以通过getItem()和releaseItem()方法来管理。
        //
        checkedOut=new boolean[size];
        available=new Semaphore(size,true);
        for (int i = 0; i < size; i++) {
            try{
               items.add(classObject.newInstance());
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    }

    //如果没有任何信号量可用,available将阻塞调用过程
    public T checkOut() throws InterruptedException{
        available.acquire();
        return getItem();
    }
    //checkIn(),如果被迁入的对象有效,则会向信号量返回一个许可证。
    public void checkIn(T x){
        if(releaseItem(x)){
            available.release();
        }
    }

    private synchronized T getItem(){
        for (int i = 0; i <size ; i++) {
            if(!checkedOut[i]){
                checkedOut[i]=true;
                return items.get(i);
            }
        }
        return null;
    }

    private synchronized boolean releaseItem(T item){
        int index=items.indexOf(item);
        if(index==-1) return false;
        if(checkedOut[index]){
            checkedOut[index]=false;
            return true;
        }
        return false;
    }

}
package com21concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * Created by Panda on 2018/6/1.
 */
class Fat{
    private volatile double d;
    private static int counter=0;
    private final int id=counter++;

    public Fat() {
        for (int i = 0; i <10000 ; i++) {
            d+=(Math.PI+Math.E)/(double)i;
        }
    }

    public void operation(){
        System.out.println(this);
    }
    public String toString(){
        return "Fat id:"+id;
    }
}

class CheckoutTask<T> implements Runnable{
    private static int counter=0;
    private final int id=counter++;
    private Pool<T> pool;

    public CheckoutTask(Pool<T> pool) {
        this.pool = pool;
    }


    @Override
    public void run() {
       try{
           T item=pool.checkOut();
           System.out.println(this+"checked out "+item);
           TimeUnit.SECONDS.sleep(1);
           System.out.println(this+"checking in "+item);
           pool.checkIn(item);
       }catch (InterruptedException e){

       }
    }

    public String toString(){
        return "CheckoutTask "+id+" ";
    }
}
public class SemaphoreDemo {
    final static int SIZE=25;

    public static void main(String[] args) throws Exception {
        final Pool<Fat> pool= new Pool<>(Fat.class,SIZE);
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < SIZE; i++) {
            executorService.execute(new CheckoutTask<Fat>(pool));
        }
        System.out.println("All checkoutTasks created");
        List<Fat> list = new ArrayList<>();
        for (int i = 0; i <SIZE ; i++) {
            Fat fat = pool.checkOut();
            System.out.println(i+":main() thread checked out");
            fat.operation();
            list.add(fat);
        }

        Future<?> blocked=executorService.submit(new Runnable() {
            @Override
            public void run() {
                try{
                    pool.checkOut();
                }catch (InterruptedException e){
                    System.out.println("checkOut() Interrupted");
                }
            }
        });

        TimeUnit.SECONDS.sleep(2);
        blocked.cancel(true);
        System.out.println("checking in objects in"+list);
        for(Fat fat:list){
            pool.checkIn(fat);
        }
        for(Fat fat:list){
            pool.checkIn(fat);
        }
        executorService.shutdownNow();
    }
}

猜你喜欢

转载自blog.csdn.net/panda_____/article/details/80543602