使用背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实现重复利用。类似生活中的公共交通工具。
使用线程池的好处
好处:
- 提高响应速度(减少了创建新线程的时间)
- 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
- 便于线程管理(…
- corePoolSize: 核心池的大小
- maximumPoolSize:最大线程数
- keepAliveTime:线程没有任务时最多保持多长时间后会终止
使用线程池
- JDK 5.0起提供了线程池相关APl:
ExecutorService
和Executors
- ExecutorService真正的线程池接口。常见子类ThreadPoolExecutor
- void execute(Runnable command) :执行任务/命令,没有返回值,一般用来执行Runnable
- Future submit(Callable task):执行任务,有返回值,一般又来执行Callable
- void shutdown() :关闭连接池
- Executors: 工具类、线程池的工厂类,用于创建并返回不同类型的线程池
方式一:实现Runnable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class Testpool {
public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread());
service.shutdown(); }
}
class MyThread implements Runnable{
@Override public void run() { System.out.println(Thread.currentThread().getName()); } }
|
可以看见4个池子
方式二:实现Callable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class NumThread implements Callable { @Override public Object call() throws Exception { return Thread.currentThread().getName(); } }
public class Test{ public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(3); Future submit = service.submit(new NumThread()); Future submit1 = service.submit(new NumThread()); Future submit2 = service.submit(new NumThread());
System.out.println(submit.get()); System.out.println(submit1.get()); System.out.println(submit2.get()); service.shutdown();
} }
|
创建线程池的4种方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 容量大小为:Integer.MAX_VALUE 1.newCachedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 2.newFixedThreadPool
创建一个定长线程池,支持定时及周期性任务执行。 3.newScheduledThreadPool
保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 4..newSingleThreadExecutor
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class NumThread1 implements Runnable { @Override public Object call() throws Exception { return Thread.currentThread().getName(); }
}
public class Cached{ public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.shutdown(); } }
|
1 2 3 4 5 6
| ExecutorService cachedThreadPool = Executors.newScheduledThreadPool(3); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.shutdown();
|
1 2 3 4 5 6
| ExecutorService cachedThreadPool = Executors.newSingleThreadExecutor(); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.submit(new NumThread1()); cachedThreadPool.shutdown();
|
总结
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public class ThreadNew {
public static void main(String[] args) throws ExecutionException, InterruptedException { new MyThread1().start();
new Thread(new MyThread2()).start();
ExecutorService service = Executors.newFixedThreadPool(3); Future submit = service.submit(new MyCallable()); System.out.println(submit.get());
}
}
class MyThread1 extends Thread { @Override public void run() { System.out.println("1"); } }
class MyThread2 implements Runnable { @Override public void run() { System.out.println("2"); } }
class MyCallable implements Callable {
@Override public Integer call() throws Exception { return 100; } }
|