使用Java.util.concurrent包下的類
一些概念:
- 阻塞:阻塞調用是指調用結果返回之前,當前線程會被掛起。函數只有在得到結果之後纔會返回
採用LockSupport.park()
阻塞住線程, 採用LockSupport.unpark(Thread)
釋放進程。 - 隊列:生產者消費者模式首選數據模式爲隊列。Java提供的線程安全的隊列可分爲阻塞隊列(BlockingQueue)和非阻塞隊列(ConcurrentLinkedQueue).根據需要選擇阻塞隊列還是非阻塞隊列。
- 線程安全:指類內共享的全局變量的訪問必須保證是不受多線程形式影響的。如果由於多線程的訪問(比如修改、遍歷、查看)而使這些變量結構被破壞或者針對這些變量操作的原子性被破壞,則這個類就不是線程安全的。
阻塞隊列: BlockingQueue
實現類:
詳細介紹:http://www.cnblogs.com/geningchao/p/6638781.html
ArrayBlockingQueue: 規定大小
LinkedBlockingQueue: 大小可規定,不規定爲Interger.MAX_VALUE來決定。
PriorityBlockingQueue: 更加優先級來決定出隊列順序
SynchronousQueue: 無緩存的等待隊列。
DelayQueue: 延遲隊列
方法:
操作 | 失敗 | 拋出異常 | 特殊值false | 阻塞 超時 |
---|---|---|---|---|
插入 | Add(e) | Offer(e) | Put(e) | Offer(e,time, TimeUnit) |
移除 | Remove() | Poll() | Take() | Poll(time, TimeUnit) |
檢查 | element | Peek() |
雙端阻塞隊列:BlockingDeque
該接口是一種雙端隊列,向其中加入元素或取出元素都是現成安全的,如果不能對雙端隊列進行加入或刪除元素,則會阻塞線程。
非阻塞隊列: ConcurrentHashMap
多線程:
聲明線程的方法:
- 繼承Thread extends Thread();
- 實現接口Runnable implements Runnable(); 無返回值。 一般運行:new Thread(new
Runable()).start(); - implements Callable (有返回值); 執行 ,Callable.call()
異步執行框架Executor框架:
支持多種不同類型的任務執行策略,提供了一種標準的方法將任務的提交過程和執行過程解耦開發,基於生產者-消費者模式,其提交任務的線程相當於生產者,執行任務的線程相當於消費者,並用Runnable來表示任務,Executor的實現還提供了對生命週期的支持,以及統計信息收集,應用程序管理機制和性能監視等機制。
Executor 子接口 ExecutorService
實現類:
AbstractExecutorService: 默認實現類
ScheduledExecutorService: 一個可定時調度任務的接口
ScheduledThreadPoolExecutor: ScheduledExecutorService實現類
ThreadPoolExecutor: 線程池,通過調用Executors中的靜態方法來創建線程池並返回一個ExecutorService對象。
Executor的生命週期:
- 運行 創建即運行;
- 關閉 shutdown 執行完已提交的任務關閉
- 終止 shutdownNow 強制終止所有運行中的任務,並不允許添加新的任務。
Executor 執行任務:
Executor.submit(new Runnable()); 或 Executor.execute(new Runnable())
Future f = Executor.submit(new Callable); 有返回值 f.get()
Executors
提供一系列靜態工廠方法用於創建各種線程池
//創建方法
//創建可重用且固定線程數的線程池。數量夠了再來則等待。
ExecutorService executor = Executors.newFixedThreadPool(int num)
//創建一個單線程的Executor. 如果異常結束則新建線程來執行後續任務
Executors.newSingleThreadExecutor()
//創建一個可延遲執行或定期執行的線程池
Executors.newScheduledThreadPool(int corePoolSize)
//創建可緩存的線程池。六十秒沒用則清除。
Executors.newCachedThreadPool()
示例:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import com.thunisoft.artery.report.crs.engine.callback.imp.Callback;
import com.thunisoft.artery.services.config.ArteryConfigUtil;
@Service
public class RequestThreadHandle {
private static int queue_size;
private static int EXE_SIZE;
private static BlockingQueue<ThreadBean> queue;
private static ThreadPoolExecutor executorService;
//初始化
@PostConstruct
public void init() {
int queue_size = 200;
queue = new LinkedBlockingQueue<ThreadBean>(queue_size);
orc_size = 10;
executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(orc_size);
}
/**
* 添加到隊列中
* @param httpBean
* @return
* @throws InterruptedException
*/
public boolean offerQuery(ThreadBean httpBean) throws InterruptedException {
return queue.offer(httpBean);
}
@PostConstruct
public void consume() throws InterruptedException, ExecutionException{
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
ThreadBean httpBean = queue.poll();
if (httpBean == null) {
continue;
}
executorService.submit(httpBean);
}
}
}
});
t.start();
}
//銷燬
@PreDestroy
public void CloseExe() {
executorService.shutdown();
}
}
public class ThreadBean extends Thread{
@Override
public void run() {
//do your thing
}
}