上QQ阅读APP看书,第一时间看更新
1.1.14 使用Semaphore创建字符串池
类Semaphore可以有效地对并发执行任务的线程数量进行限制,这种功能可以应用在pool池技术中,可以设置同时访问pool池中数据的线程数量。
本实验的功能是同时有若干个线程可以访问池中的数据,但同时只有一个线程可以取得数据,使用完毕后再放回池中。
创建测试用的项目Semaphore_Pool_List,类ListPool.java代码如下:
package tools; 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 ListPool { int poolMaxSize = 3; int semaphorePermits = 5; private List<String> list = new ArrayList<String>(); private Semaphore concurrencySemaphore = new Semaphore(semaphorePermits); private ReentrantLock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public ListPool() { super(); for (int i = 0; i < poolMaxSize; i++) { list.add("高洪岩" + (i + 1)); } } public String get() { String getString = null; try { concurrencySemaphore.acquire(); lock.lock(); while (list.size() == 0) { condition.await(); } getString = list.remove(0); lock.unlock(); } catch (InterruptedException e) { e.printStackTrace(); } return getString; } public void put(String stringValue) { lock.lock(); list.add(stringValue); condition.signalAll(); lock.unlock(); concurrencySemaphore.release(); } }
线程类MyThread.java代码如下:
package extthread; import tools.ListPool; public class MyThread extends Thread { private ListPool listPool; public MyThread(ListPool listPool) { super(); this.listPool = listPool; } @Override public void run() { for (int i = 0; i < Integer.MAX_VALUE; i++) { String getString = listPool.get(); System.out.println(Thread.currentThread().getName() + " 取得值 " + getString); listPool.put(getString); } } }
运行类Run.java代码如下:
package test; import tools.ListPool; import extthread.MyThread; public class Run { public static void main(String[] args) { ListPool pool = new ListPool(); MyThread[] threadArray = new MyThread[12]; for (int i = 0; i < threadArray.length; i++) { threadArray[i] = new MyThread(pool); } for (int i = 0; i < threadArray.length; i++) { threadArray[i].start(); } } }
程序运行结果如图1-26所示。
图1-26 部分运行结果
为了验证更多的情况,更改类代码如下:
private int poolMaxSize = 5; private int semaphorePermits = 3;
程序正常运行,不出现异常。更改类代码如下:
private int poolMaxSize = 5; private int semaphorePermits = 5;
程序正常运行,也不出现异常。