線程在併發程序中用的比較多,建立線程原始的有最基本的建立方式:緩存
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
//todo
}
}).start();
}複製代碼
但若是經過這樣創線程那就有點low了:bash
1)每次經過new Thread()建立對象性能不佳。併發
2)線程缺少統一管理,可能無限制新建線程,相互之間競爭,及可能佔用過多系統資源致使死機或oom。ide
3)缺少更多功能,如定時執行、按期執行、線程中斷。性能
這裏能夠用到Java提供的4種線程池來建立,分別爲:spa
下面來比較一下這四種線程池:線程
public static void main(String[] args) {
ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
for (int i=0; i<10; i++){
final int index = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e){
}
cacheThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("第" +index +"個線程" +Thread.currentThread().getName());
}
});
}
}複製代碼
輸出結果爲:code
能夠看出當執行第二個任務時第一個任務已經完成,會複用執行第一個任務的線程,而不用去從新建立線程。cdn
public static void main(String[] args) {
ExecutorService fixedThreadPool =Executors. newFixedThreadPool(3);
for (int i =1; i<=5;i++){
final int index=i ;
fixedThreadPool.execute(new Runnable(){
@Override
public void run() {
try {
System.out.println("第" +index + "個線程" +Thread.currentThread().getName());
Thread.sleep(1000);
} catch(InterruptedException e ) {
}
}
});
}
}複製代碼
fixThreadPool會定義開啓的線程數,例子中開啓了三個,因此結果是前三個線程執行,第4個線程要等待1秒後執行。對象
該線程池能夠安排在給定延遲後運行命令或者按期地執行。
延遲執行示例:
//corePoolSize - 池中所保存的線程數,即便線程是空閒的也包括在內。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)複製代碼
public static void main(String[] args) {
ScheduledExecutorService scheduledThreadPool= Executors.newScheduledThreadPool(3);
scheduledThreadPool.schedule(new Runnable(){
@Override
public void run() {
System.out.println("延遲3秒後執行");
}
}, 3, TimeUnit.SECONDS);
}複製代碼
上述實例會在開啓3秒後執行。
按期執行示例:
public static void main(String[] args) {
ScheduledExecutorService scheduledThreadPool= Executors.newScheduledThreadPool(3);
scheduledThreadPool.scheduleAtFixedRate(new Runnable(){
@Override
public void run() {
System.out.println("延遲3秒後執行");
}
}, 1, 3, TimeUnit.SECONDS); //1:initialDelay, 3:period
}複製代碼
上述示例會在開啓後延遲1秒執行,而後每3秒執行一次。
public static void main(String[] args) {
ExecutorService singleThreadPool= Executors.newSingleThreadExecutor();
for(int i=1;i<=5;i++){
int index=i;
singleThreadPool.execute(new Runnable(){
@Override
public void run() {
try{
System.out.println("第"+index+"個線程");
Thread.sleep(2000);
}catch(InterruptedException e) {
e.printStackTrace();
}
} });
}
}複製代碼
會每2秒創一個線程,並且是順序的執行各個任務,而且在任意給定的時間不會有多個線程是活動的,其實與newFixedThreadPool(1)效果是同樣的。