前些天由于用到多线程处理,所以想到线程池,搜集了网上的一些资料,再分析改进一下,有了下面的东西。 首先是个读取配置文件的类:
1 package org.ofbiz.smsSend; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.util.Properties; 8 9 /** */ /** 10 * @author zxub 2005-11-11 16:44:55 11 */ 12 13 public class UtilProperties 14 { 15 16 //设置默认的配置文件路径 17 private String fileName = System.getProperty("user.dir") 18 + "/base/config.properties"; 19 private Properties prop; 20 private FileInputStream in; 21 private FileOutputStream out; 22 23 /** *//** 24 * 自定义配置文件路径 25 * @param fileName 26 */ 27 public UtilProperties(String filePath) 28 { 29 this.fileName = System.getProperty("user.dir")+filePath; 30 getFile(); 31 } 32 33 public UtilProperties() 34 { 35 getFile(); 36 } 37 38 /** *//** 39 * 获取配置文件 40 */ 41 private void getFile() 42 { 43 File file = new File(this.fileName); 44 try 45 { 46 in = new FileInputStream(file); 47 prop = new Properties(); 48 // 载入文件 49 prop.load(in); 50 in.close(); 51 } 52 catch (FileNotFoundException e) 53 { 54 System.err.println("配置文件config.properties找不到!!"); 55 } 56 catch (IOException e) 57 { 58 System.err.println("读取配置文件config.properties错误!!"); 59 } 60 } 61 62 /** *//** 63 * 列出所有的配置文件内容 64 */ 65 public void list() 66 { 67 prop.list(System.out); 68 } 69 70 /** *//** 71 * 指定配置项名称,返回配置值 72 * 73 * @param itemName 74 * String 75 * @return String 76 */ 77 78 public String getValue(String itemName) 79 { 80 81 return prop.getProperty(itemName); 82 83 } 84 85 /** *//** 86 * 设置配置项名称及其值 87 * 88 * @param itemName 89 * String 90 * @param value 91 * String 92 */ 93 94 public void setValue(String itemName, String value) 95 { 96 prop.setProperty(itemName, value); 97 } 98 99 /** *//**100 * 保存配置文件,指定文件名和抬头描述101 * 102 * @param fileName103 * String104 * @param description105 * String106 * @throws Exception107 */108 public void saveFile()109 {110 try111 {112 File f = new File(this.fileName);113 out = new FileOutputStream(f);114 prop.store(out, "");115 out.close();116 }117 catch (FileNotFoundException e)118 {119 e.printStackTrace();120 }121 catch (IOException e)122 {123 System.err.println("配置文件config.properties写入错误!!");124 }125126 }127128 /** *//**129 * 删除一个属性130 * 131 * @param value132 * String133 */134135 public void deleteValue(String value)136 {137 prop.remove(value);138 }139 140 public void changeFile(String filePath)141 {142 this.fileName = System.getProperty("user.dir")+filePath;143 getFile();144 }145146 147 public static void main(String[] args)148 {149 UtilProperties up = new UtilProperties();150 up.list();151 up.changeFile("/logs/config.properties");152 up.list();153 System.out.println("\n"+up.getValue("tmpSavePath"));154 }155156} 157 接着,是要做事的类,我写了一个接口,只有一个方法doWork(),在线程池中,一旦一个线程获得一个工作任务,线程就会调用工作任务的doWork()方法。 package org.ofbiz.smsSend; public interface Work { public abstract void doWork();} 然后,就是主要的线程池类了: 1 /** */ /** 2 * @author zxub 2005-12-3 19:44:33 3 */ 4 package org.ofbiz.smsSend; 5 6 import java.util.ArrayList; 7 import java.util.Iterator; 8 import java.util.LinkedList; 9 import java.util.Timer; 10 11 public class ThreadPool 12 { 13 private static final UtilProperties utilProp = new UtilProperties(); 14 private static int minPools = Integer.parseInt(utilProp 15 .getValue("minPools")); 16 private static int maxPools = Integer.parseInt(utilProp 17 .getValue("maxPools")); 18 private static int checkThreadPeriod = Integer.parseInt(utilProp 19 .getValue("checkThreadPeriod")) * 60 * 1000; 20 private static ArrayList workThreadList; // 工作线程列表,保存所有的线程 21 private static LinkedList taskList = null; // 工作任务列表,保存将要执行的工作任务 22 private static int totalThread = 0; // 总线程数 23 private static int freeThreadCount = 0; // 未被使用的线程数目 24 private java.util.Timer timer = null; // 定时器 25 private static Object o = new Object(); 26 27 private static ThreadPool pool=new ThreadPool(); 28 29 public static void setMinPools(int minPools) 30 { 31 ThreadPool.minPools = minPools; 32 } 33 34 public static void setMaxPools(int maxPools) 35 { 36 ThreadPool.maxPools = maxPools; 37 } 38 39 public static void setCheckThreadPeriod(int checkThreadPeriod) 40 { 41 ThreadPool.checkThreadPeriod = checkThreadPeriod; 42 } 43 44 private ThreadPool() 45 { 46 workThreadList = new ArrayList(); 47 taskList = new LinkedList(); 48 //初始化线程池 49 for (int i = 0; i < ThreadPool.minPools; i++) 50 { 51 WorkerThread temp = new WorkerThread(); 52 totalThread = totalThread + 1; 53 workThreadList.add(temp); 54 temp.start(); 55 try 56 { 57 Thread.sleep(100); 58 } 59 catch (Exception e) 60 { 61 } 62 } 63 timer = new Timer(true); // 启动定时器 64 timer.schedule(new CheckThreadTask(this), 0, checkThreadPeriod); 65 } 66 67 public static ThreadPool getInstance() 68 { 69 return pool; 70 } 71 72 public synchronized void run(Work work) 73 { 74 if (freeThreadCount == 0) 75 { 76 if (totalThread < maxPools) 77 { 78 WorkerThread temp = new WorkerThread(); 79 totalThread = totalThread + 1; 80 workThreadList.add(temp); 81 temp.start(); 82 synchronized (taskList) 83 { 84 taskList.add(work); 85 taskList.notify(); 86 } 87 } 88 else 89 { 90 while (freeThreadCount == 0) 91 { 92 try 93 { 94 Thread.sleep(200); 95 } 96 catch (InterruptedException e) 97 { 98 } 99 }100 synchronized (taskList)101 {102 taskList.add(work);103 taskList.notify();104 }105 }106 }107 else108 {109 synchronized (taskList)110 {111 taskList.add(work);112 taskList.notify();113 }114 }115 }116117 /** *//**118 * 检查工作线程列表,将非活动状态的线程换成活动状态的线程,保证线程池中的线程可用119 *120 */121 public synchronized void checkAllThreads()122 {123124 Iterator threadIterator = workThreadList.iterator();125126 while (threadIterator.hasNext())127 { // 逐个遍厉128 WorkerThread workThread = (WorkerThread) threadIterator.next();129130 if (!(workThread.isAlive()))131 {132 // 如果处在非活动状态时133 workThread = new WorkerThread(); // 重新生成1个线程134 workThread.start(); // 启动135 }136 }137 }138139 public static void printInfo()140 {141 System.out.println("minPools:" + minPools);142 System.out.println("maxPools:" + maxPools);143 System.out.println("checkThreadPeriod:" + checkThreadPeriod);144 System.out.println("totalThread=" + totalThread);145 System.out.println("workThreadList.size()=" + workThreadList.size());146 }147 148 /** *//**149 * 线程池中的工作线程类,由工作线程执行我们要进行的操作150 */151 class WorkerThread extends Thread152 {153 boolean running = true;154 Work work;155156 public void run()157 {158 while (running)159 {160 synchronized (o)161 {162 freeThreadCount++; //一进来说明多了一个可用线程163 }164 synchronized (taskList)165 {166 while (taskList.size() == 0) //当工作任务列表为空时,等待167 {168 try169 {170 taskList.wait();171 if (!running) return;172 }173 catch (InterruptedException e)174 {175 }176 }177 synchronized (o)178 {179 freeThreadCount--; //得到一个工作,可用线程要减1180 }181 work = (Work) taskList.removeLast(); //从任务列表处获得一个任务182 if (work == null) return;183 }184 work.doWork();185 }186 }187 }188} 189 定时器自动查失效的线程,用到的方法如下: 1 package org.ofbiz.smsSend; 2 3 import java.util.TimerTask; 4 5 public class CheckThreadTask extends TimerTask 6 { 7 private static boolean isRunning = false; 8 private ThreadPool pool; 910 public CheckThreadTask(ThreadPool pool)11 {12 this.pool = pool;13 }1415 public void run()16 {17 if (!isRunning)18 {19 isRunning = true;20 pool.checkAllThreads();21 isRunning = false;22 }23 }24} 25 最后,配置文件的内容如下 1 # ---------------- 线程池配置信息 ----------------- 2 # 3 #线程池最小线程 4 minPools = 10 5 #线程池最大线程 6 maxPools = 100 7 #检查线程池中线程的周期(分钟) 8 checkThreadPeriod = 5 ok,要用的时候,调用方法如下: 1 ThreadPool.getInstance().run( new (实现了work接口的类));转载于:https://www.cnblogs.com/zxub/archive/2005/12/09/293806.html