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;

程序正常运行,也不出现异常。