使用Semaphore 实现一个字符串池
类SemaPhore可以有效地对并发执行任务的线程数量进行限制,可以用在pool池技术中,
可以设置同时访问pool池中数据的线程数量。
目的:实现同时有若干个线程可以访问池中的数据,但同时只有一个线程可以取得数据,使用后再放回。
代码:
package com.lhc.concurrent.semaphore.StringPool;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class StringPoolService {
private int poolMaxSize = 3;
//同时可以有5个线程访问这个pool
private int semaphorePermits = 5;
private Semaphore semaphore = new Semaphore(semaphorePermits);
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private List<String> list = new ArrayList<>();
public StringPoolService() {
super();
//初始化一个list
for (int i = 0; i < poolMaxSize; i++){
list.add("String " + i);
}
}
public String get(){
String getString = null;
try {
semaphore.acquire();
//加锁,能保证这段代码同一时刻只有一个线程在运行
lock.lock();
while (list.size() == 0){
//如果pool为空,等待
condition.await();
}
getString = list.remove(0);
//解锁
lock.unlock();
}catch (InterruptedException e){
e.printStackTrace();
}
return getString;
}
public void put(String str){
//加锁
lock.lock();
list.add(str);
//填充以后通知,get方法就不再await
condition.signalAll();
//解锁
lock.unlock();
semaphore.release();
}
}
测试类
/**
* 类Semaphore 可以有效地对并发执行任务的线程数量进行限制
* 创建一个字符串池,,同时有若干个线程可以访问池中的数据,但同时只有一个线程可以取得数据,使用完毕再放回
*/
package com.lhc.concurrent.semaphore.StringPool;
public class StringPoolThread extends Thread {
private StringPoolService stringPoolService;
public StringPoolThread(StringPoolService stringPoolService) {
super();
this.stringPoolService = stringPoolService;
}
@Override
public void run() {
for (int i = 0; i < 64; i++) {
//取了再放进去
String s = stringPoolService.get();
System.out.println(Thread.currentThread().getName() + " 取得值 " + s);
stringPoolService.put(s);
}
}
public static void main(String[] args) {
StringPoolService stringPoolService = new StringPoolService();
StringPoolThread[] stringPoolThreads = new StringPoolThread[10];
for (int i = 0; i < stringPoolThreads.length; i++) {
stringPoolThreads[i] = new StringPoolThread(stringPoolService);
}
for (int i = 0; i < stringPoolThreads.length; i++) {
stringPoolThreads[i].start();
}
}
}
测试结果
Thread-1 取得值 String 1
Thread-0 取得值 String 0
Thread-2 取得值 String 2
Thread-7 取得值 String 1
Thread-2 取得值 String 0
Thread-1 取得值 String 1
Thread-7 取得值 String 2
Thread-3 取得值 String 0
Thread-1 取得值 String 1
Thread-3 取得值 String 2
Thread-2 取得值 String 0
Thread-7 取得值 String 2
Thread-1 取得值 String 1
Thread-7 取得值 String 2
Thread-2 取得值 String 0
Thread-7 取得值 String 2
Thread-1 取得值 String 1
Thread-3 取得值 String 2
Thread-2 取得值 String 0
Thread-3 取得值 String 2
Thread-5 取得值 String 1
Thread-4 取得值 String 2
Thread-3 取得值 String 0
Thread-4 取得值 String 2
Thread-5 取得值 String 1
Thread-4 取得值 String 2
Thread-8 取得值 String 0
Thread-4 取得值 String 2
Thread-6 取得值 String 1
Thread-0 取得值 String 2
Thread-8 取得值 String 0
Thread-0 取得值 String 2
Thread-6 取得值 String 1
Thread-0 取得值 String 2
Thread-8 取得值 String 0
Thread-0 取得值 String 2
Thread-6 取得值 String 1
Thread-4 取得值 String 2
Thread-8 取得值 String 0
Thread-9 取得值 String 2
Thread-6 取得值 String 1
Thread-9 取得值 String 2
Thread-8 取得值 String 0
Thread-9 取得值 String 2
Thread-6 取得值 String 1
Thread-9 取得值 String 2
Thread-5 取得值 String 0
Thread-9 取得值 String 1
Thread-5 取得值 String 2
Thread-5 取得值 String 0