在写后台程序的时候我们往往会用到多线程处理办法,为了尽量减少创建和销毁线程的系统开支,需要通过线程池的模式来维处于并发状态的多线程,jdk1.5 提供了较为方便的线程池维护类库,java.util.concurrent 在并发编程中很常用的实用工具类。
下面简单介绍下使用 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); 是不能少的,感觉是有点别扭,如果只是查询之类的处理就可以不要控制,直接将任务添加到线程池中,如果需要数据处理的话就需要判断下当前线程池中有没有空闲的线程再取数据处理。对这一行我的理解是放弃当前线程对其他线程的处理时间片,否则还没来得及控制循环就已经做完了。
分享到:
相关推荐
下面是使用 Executors 工厂类创建线程池的示例代码: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FixedThreadPool { public static void main...
在Java中,使用`ExecutorService`和`ThreadPoolExecutor`来创建线程池,而不是直接使用`Executors`,因为`Executors`创建的线程池可能会导致资源耗尽的问题。 集合是Java中存储数据的主要工具,包括List、Set和Map...
jdk自带的线程池可以通过Executors工厂类来创建,Executors工厂类提供了多种创建线程池的方法,下面我们来看下使用示例: 1. newFixedThreadPool(固定大小的线程池) 使用newFixedThreadPool方法可以创建一个固定...
Java从JDK 1.5版本开始引入了线程池,使得开发者不再需要手动创建和销毁线程,而是通过线程池来管理和复用线程。 1. **什么是线程池?** 线程池是预先创建并维护的一组线程集合。这些线程在需要时被分配给任务执行...
在JDK 1.5版本之前,Java对线程池的支持非常有限,而在JDK 1.5之后,加入了java.util.concurrent包,其中包含了一系列关于线程池的接口和类,极大地丰富了线程池的应用场景和管理方式。 线程池的主要作用是限制系统...
然而,自JDK 1.5开始,随着`java.util.concurrent`包的引入,Java线程池的功能得到了极大的增强,为开发者提供了更加高效且易于管理的线程管理方式。 #### 二、线程池的作用与必要性 线程池的主要功能在于限制系统...
在实际应用中,通常使用`Executors`工厂类来创建线程池,如`newFixedThreadPool`创建固定大小的线程池,`newCachedThreadPool`创建可缓存的线程池等。然而,对于大规模并发场景,建议直接实例化`ThreadPoolExecutor`...
而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()等创建线程池的方法,...
在Java中,`java.util.concurrent.ExecutorService`接口定义了线程池的基本行为,而`java.util.concurrent.Executors`类提供了创建线程池的静态工厂方法。常见的线程池类型包括: - `newFixedThreadPool(int ...
创建线程池时需要指定`corePoolSize`(核心线程数)、`maximumPoolSize`(最大线程数)、`keepAliveTime`(非核心线程的空闲存活时间)以及`workQueue`(工作队列),队列类型的选择会影响线程池的行为,如无界队列(FIFO)、...
从JDK 1.5开始,Java并发API得到了增强,提供了更为强大的并发工具和库,其中就包括线程池的实现。线程池的主要优势在于可以重用线程,减少线程创建和销毁带来的开销,同时还可以有效控制并发数和管理资源。 在给出...
例如,以下代码展示了如何使用`newSingleThreadExecutor`创建线程池并执行任务: ```java ExecutorService pool = Executors.newSingleThreadExecutor(); Thread t1 = new MyThread(); Thread t2 = new MyThread();...
这篇文章结合Doug Lea大神在JDK1.5提供的JCU包,分别从线程池大小参数的设置、工作线程的创建、空闲线程的回收、阻塞队列的使用、任务拒绝策略、线程池Hook等方面来了解线程池的使用,其中涉及到一些细节包括不同...
从JDK1.5开始,把工作单元与执行机制分离开来。工作单元包括Runnable和Callable,而执行机制由Executor框架提供。 2. 框架结构 Executor框架采用的是两级调度模型。在HotSpot VM的线程模型中,Java线程被一对一...
线程池的使用通常包括创建线程池对象、提交任务和关闭线程池等步骤。 总的来说,Java中的线程通信和管理是多线程编程的关键,理解并掌握wait(), notify(), notifyAll()方法、ReentrantLock以及线程池的使用,能够...
#### 十一、为什么不建议用Executors创建线程池 - **默认无界队列**: - Executors提供的一些工厂方法默认使用无界队列,可能导致OOM。 - **配置不当**: - 如果没有正确配置线程池参数,可能会导致性能问题或资源...
java.util.concurrent.Executors提供了一个java.util.concurrent.Executor接口的实现用于创建线程池。线程池技术主要解决处理器单元内多个线程执行的问题,可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐...
这段代码展示了如何使用JDK 1.6中的并发工具包创建线程池并执行任务,是JDK 1.6强大功能的一个具体体现。 #### 四、结论 JDK 1.6作为Java SE平台的一个重要版本,不仅引入了许多新特性,还对现有的API进行了大量...
2. 创建线程池:Executors提供newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor等工厂方法。 3. 线程池优点:减少线程创建和销毁的开销,更好地控制并发数量,提高系统资源利用率。 六、死锁、...
- Executors框架的使用,创建线程池。 7. **IO流与NIO** - 流的概念,了解字节流和字符流的区别。 - 文件操作,包括读写、复制、追加等。 - 使用缓冲区提升IO效率。 - NIO(非阻塞I/O)的特点和使用场景,包括...