[TOC]
# 概念
線程池,其實就是一個容納多個線程的容器,其中的線程可以反復使用,省去了頻繁創建線程對象的操作,無需反復創建線程而消耗過多資源
# 方法一:Runnable接口
通常,線程池都是通過線程池工廠創建,再調用線程池中的方法獲取線程,再通過線程去執行任務方法。
* Executors:線程池創建工廠類
- public static ExecutorService newFixedThreadPool(int nThreads):返回線程池對象
* ExecutorService:線程池類
- Future<?> submit(Runnable task):獲取線程池中的某一個線程對象,并執行
* Future接口:用來記錄線程任務執行完畢后產生的結果。線程池創建與使用
* 使用線程池中線程對象的步驟:
- 創建線程池對象
- 創建Runnable接口子類對象
- 提交Runnable接口子類對象
- 關閉線程池
## 代碼
~~~
public class ThreadPoolDemo {
public static void main(String[] args) {
//創建線程池對象
ExecutorService service = Executors.newFixedThreadPool(2);//包含2個線程對象
//創建Runnable實例對象
MyRunnable r = new MyRunnable();
//自己創建線程對象的方式
//Thread t = new Thread(r);
//t.start(); ---> 調用MyRunnable中的run()
//從線程池中獲取線程對象,然后調用MyRunnable中的run()
service.submit(r);
//再獲取個線程對象,調用MyRunnable中的run()
service.submit(r);
service.submit(r);
//注意:submit方法調用結束后,程序并不終止,是因為線程池控制了線程的關閉。將使用完的線程又歸還到了線程池中
//關閉線程池
service.shutdown();
}
}
~~~
* Runnable接口實現類
~~~
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("我要一個教練");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("教練來了: " +Thread.currentThread().getName());
System.out.println("教我游泳,交完后,教練回到了游泳池");
}
}
~~~
# 方法二:Callable接口
* Callable接口:與Runnable接口功能相似,用來指定線程的任務。其中的call()方法,用來返回線程任務執行完畢后的結果,call方法可拋出異常。
* ExecutorService:線程池類
- <T> Future<T> submit(Callable<T> task):獲取線程池中的某一個線程對象,并執行線程中的call()方法
* Future接口:用來記錄線程任務執行完畢后產生的結果。線程池創建與使用
* 使用線程池中線程對象的步驟:
- 創建線程池對象
- 創建Callable接口子類對象
- 提交Callable接口子類對象
- 關閉線程池
## 代碼
~~~
public class ThreadPoolDemo {
public static void main(String[] args) {
//創建線程池對象
ExecutorService service = Executors.newFixedThreadPool(2);//包含2個線程對象
//創建Callable對象
MyCallable c = new MyCallable();
//從線程池中獲取線程對象,然后調用MyRunnable中的run()
service.submit(c);
//再獲取個教練
service.submit(c);
service.submit(c);
//注意:submit方法調用結束后,程序并不終止,是因為線程池控制了線程的關閉。將使用完的線程又歸還到了線程池中
//關閉線程池
service.shutdown();
}
}
~~~
* Callable接口實現類,call方法可拋出異常、返回線程任務執行完畢后的結果
~~~
public class MyCallable implements Callable {
@Override
public Object call() throws Exception {
System.out.println("我要一個教練:call");
Thread.sleep(2000);
System.out.println("教練來了: " +Thread.currentThread().getName());
System.out.println("教我游泳,交完后,教練回到了游泳池");
return null;
}
}
~~~
# 返回兩個數相加的結果
要求:通過線程池中的線程對象,使用Callable接口完成兩個數求和操作
* Future接口:用來記錄線程任務執行完畢后產生的結果。線程池創建與使用
- V get() 獲取Future對象中封裝的數據結果
代碼演示:
~~~
public class ThreadPoolDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//創建線程池對象
ExecutorService threadPool = Executors.newFixedThreadPool(2);
//創建一個Callable接口子類對象
//MyCallable c = new MyCallable();
MyCallable c = new MyCallable(100, 200);
MyCallable c2 = new MyCallable(10, 20);
//獲取線程池中的線程,調用Callable接口子類對象中的call()方法, 完成求和操作
//<Integer> Future<Integer> submit(Callable<Integer> task)
// Future 結果對象
Future<Integer> result = threadPool.submit(c);
//此 Future 的 get 方法所返回的結果類型
Integer sum = result.get();
System.out.println("sum=" + sum);
//再演示
result = threadPool.submit(c2);
sum = result.get();
System.out.println("sum=" + sum);
//關閉線程池(可以不關閉)
}
}
~~~
* Callable接口實現類
~~~
public class MyCallable implements Callable<Integer> {
//成員變量
int x = 5;
int y = 3;
//構造方法
public MyCallable(){
}
public MyCallable(int x, int y){
this.x = x;
this.y = y;
}
@Override
public Integer call() throws Exception {
return x+y;
}
}
~~~
- 基礎
- 編譯和安裝
- scanner類(鍵盤錄入)
- Random類(隨機數)
- 數組
- 方法
- 類
- ArrayList集合
- char與int
- eclipse
- IDEA
- 變量與常量
- 常用API
- String,StringBuffer,StringBuilder
- 正則,Date,DateFormat,Calendar
- 包裝類,System,Math,Arrays,BigInteger,BigDecimal
- 集合,迭代器,增強for,泛型
- List,set,判斷集合唯一
- map,Entry,HashMap,Collections
- 異常
- IO
- File
- 遞歸
- 字節流
- 字符流
- IO流分類
- 轉換流
- 緩沖流
- 流的操作規律
- properties
- 序列化流與反序列化流
- 打印流
- commons-IO
- IO流總結
- 多線程
- 線程池
- 線程安全
- 線程同步
- 死鎖
- lock接口
- ThreadLoad
- 等待喚醒機制
- 線程狀態
- jdbc
- DBUtils
- 連接池DBCP
- c3p0連接池
- 網絡編程
- 多線程socket上傳圖片
- 反射
- xml
- 設計模式
- 裝飾器模式
- web service
- tomcat
- Servlet
- response
- request
- session和cookie
- JSP
- EL
- JSTL
- 事務
- 監聽器Listener
- 過濾器Filter
- json
- linux安裝軟件
- 反射詳解
- 類加載器和注解
- 動態代理
- jedis
- Hibernate
- 簡介
- 創建映射文件
- Hibernate核心配置文件
- 事務和增刪改查
- HibernateUtils
- 持久化對象的三種狀態
- 檢索方式
- query
- Criteria
- SQLQuery
- 持久化類
- 主鍵生成策略
- 緩存
- 事務管理
- 關系映射
- 注解
- 優化
- struts2
- 搭建
- 配置詳解
- Action
- 結果跳轉方式
- 訪問ServletAPI方式
- 如何獲得參數
- OGNL表達式
- valueStack 值棧
- Interceptor攔截器
- spring
- 導包
- IOC和DI
- Bean獲取與實例化
- Bean屬性注入
- spring注解
- 注解分層
- junit整合
- aop
- 動態代理實現
- cglib代理實現
- aop名詞
- spring的aop
- aop-xml詳解
- aop-注解詳解
- 代理方式選擇
- jdbcTemplate
- spring事務管理
- 回滾注意
- 事務傳播屬性
- MyBatis
- MyBatis簡介
- 入門程序
- 與jdbc hibernate不同
- 原始Dao開發
- Mapper動態代理方式
- SqlMapConfig.xml配置文件
- 輸入參數pojo包裝類
- resultMap
- 動態sql
- 一對一關聯
- 一對多
- 整合spring
- 逆向工程
- maven
- maven簡介
- 倉庫
- maven目錄結構
- maven常用命令
- 生命周期
- eclipse中maven插件
- 入門程序
- 整合struct
- 依賴范圍
- 添加插件
- idea配置
- jar包沖突
- 分模塊開發
- 構建可執行的jar包(包含依賴jar包)
- springMVC
- 處理流程
- java面試
- java版本升級
- java1-8版本變更
- java9新特性
- 鎖
- java資料
- idea
- jdk版本切換
- log4j
- 入門實例
- 基本使用方法
- Web中使用Log4j
- spring中使用log4j
- java代碼優化