package com.mytest.semaphore;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;
/**
* @ClassName: TestSemaphore
* @Description:
* @Author fjp
* @Date 2021/7/1-9:53
* @Version 1.0
*/
public class PoolSemaphore<T> {
private final Semaphore usefull;
private final Semaphore useless;
private LinkedList<T> pool;
private static Object LOCK = new Object();
private void initResource(ManageResource t, int size) {
for (int i1 = 0; i1 < size; i1++) {
pool.add((T) t.getResource());
}
}
public PoolSemaphore(ManageResource t, int size) {
this.usefull = new Semaphore(size);
this.useless = new Semaphore(0);
pool = new LinkedList<>();
initResource(t, size);
}
interface ManageResource<T> {
T getResource();
}
public void returnResource(T t) throws InterruptedException {
if (t != null) {
useless.acquire();
synchronized (LOCK) {
pool.addLast(t);
// System.out.println("size最大为2,poolSize:"+pool.size());
}
usefull.release();
}
}
public T takeResource() throws InterruptedException {
usefull.acquire();
T t=null;
synchronized (LOCK) {
try {
t = pool.removeFirst();
// System.out.println("size最小为0,poolSize:"+pool.size());
}catch (Exception e){
e.printStackTrace();
}
}
useless.release();
return t;
}
}
测试类
package com.mytest.semaphore;
import org.junit.Test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @ClassName: TestPoolSemaphore
* @Description:
* @Author fjp
* @Date 2021/7/1-10:53
* @Version 1.0
*/
public class TestPoolSemaphore {
@Test
public void test() throws InterruptedException {
ExecutorService poolThread = Executors.newFixedThreadPool(50);
//池中放了了两个资源
PoolSemaphore<Resource> resourcePoolSemaphore = new PoolSemaphore<>(() -> {
return new Resource(1, "1");
}, 2);
for (int i = 0; i < 50; i++) {
poolThread.submit(() -> {
try {
Resource resource = resourcePoolSemaphore.takeResource();
// todo 100ms work
Thread.sleep(100);
resourcePoolSemaphore.returnResource(resource);
} catch (InterruptedException e) {
System.out.println("error" + e.getMessage());
e.printStackTrace();
}
});
}
Thread.sleep(100000);
}
class Resource implements PoolSemaphore.ManageResource<Integer> {
@Override
public Integer getResource() {
return null;
}
private Integer i;
private String name;
public Resource(Integer i, String name) {
this.i = i;
this.name = name;
}
}
}