在写后台程序的时候我们往往会用到多线程处理办法,为了尽量减少创建和销毁线程的系统开支,需要通过线程池的模式来维处于并发状态的多线程,jdk1.5 提供了较为方便的线程池维护类库,java.util.concurrent 在并发编程中很常用的实用工具类。
下面简单介绍下使用 Executors 创建线程池的用法:
注意:里面的 Thread.sleep(1); 是不能少的,感觉是有点别扭,如果只是查询之类的处理就可以不要控制,直接将任务添加到线程池中,如果需要数据处理的话就需要判断下当前线程池中有没有空闲的线程再取数据处理。对这一行我的理解是放弃当前线程对其他线程的处理时间片,否则还没来得及控制循环就已经做完了。
下面简单介绍下使用 Executors 创建线程池的用法:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class Test {
// 创建无界线程池,可以进行自动线程回收
public void createNewCachedThreadPool() {
// 线程池
ExecutorService exec = Executors.newCachedThreadPool();
// 只能2个线程同时访问
final Semaphore semp = new Semaphore(2);
for (int index = 0; index < 10; index++) {
final int temp = index;
Runnable run = new Runnable() {
public void run() {
try {
// 获取许可
semp.acquire();
System.out.println(Thread.currentThread() + " index:"
+ temp);
Thread.sleep((long) (Math.random() * 10000));
// 线程处理完回收
semp.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
exec.execute(run);
}
// 退出线程池
exec.shutdown();
}
// 创建固定大小线程池
public void createNewFixedThreadPool() {
// 创建只有 2 个固定线程的线程池
ExecutorService exec = Executors.newFixedThreadPool(2);
Semaphore semp = new Semaphore(2);
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
while (getAvailableThreadNumber(semp) <= 0) {
System.out.println("暂时没有空闲的线程,等待3秒再执行...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
TaskThread tt = new TaskThread(i);
tt.setSemp(semp);
exec.submit(tt);
}
exec.shutdown();
}
private synchronized int getAvailableThreadNumber(Semaphore semp) {
return semp.availablePermits();
}
// 创建单个后台线程的线程池
public void createSingleThreadPool() {
// 创建单个线程线程池
ExecutorService exec = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
TaskThread tt = new TaskThread(i);
// 设置单线程优先级为最高
tt.setPrior(Thread.MAX_PRIORITY);
exec.submit(tt);
}
exec.shutdown();
}
class TaskThread implements Runnable {
private int index;
private int prior;
private Semaphore semp;
public TaskThread() {
this.index = 0;
}
public TaskThread(int index) {
this.index = index;
}
public void setPrior(int prior) {
this.prior = prior;
}
public void setSemp(Semaphore semp) {
this.semp = semp;
}
public void run() {
try {
if (semp != null)
semp.acquire();
if (prior >= Thread.MIN_PRIORITY
&& prior <= Thread.MAX_PRIORITY) {
Thread.currentThread().setPriority(prior);
}
System.out.println(Thread.currentThread() + " index:" + index);
Thread.sleep((long) (Math.random() * 1000));
if (semp != null)
semp.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.createNewFixedThreadPool();
test.createNewCachedThreadPool();
test.createSingleThreadPool();
}
}
注意:里面的 Thread.sleep(1); 是不能少的,感觉是有点别扭,如果只是查询之类的处理就可以不要控制,直接将任务添加到线程池中,如果需要数据处理的话就需要判断下当前线程池中有没有空闲的线程再取数据处理。对这一行我的理解是放弃当前线程对其他线程的处理时间片,否则还没来得及控制循环就已经做完了。