1. 程式人生 > >Java併發學習1

Java併發學習1

java併發庫所包含的東西
Executor :具體Runnable任務的執行者。
ExecutorService :一個執行緒池管理者,其實現類有多種,我會介紹一部分。我們能把Runnable,Callable提交到池中讓其排程
Semaphore :一個計數訊號量
ReentrantLock :一個可重入的互斥鎖定 Lock,功能類似synchronized,但要強大的多。
Future :是與Runnable,Callable進行互動的介面,比如一個執行緒執行結束後取返回的結果等等,還提供了cancel終止執行緒。
BlockingQueue :阻塞佇列。
CompletionService : ExecutorService的擴充套件,可以獲得執行緒執行結果的
CountDownLatch :一個同步輔助類,在完成一組正在其他執行緒中執行的操作之前,它允許一個或多個執行緒一直等待。
CyclicBarrier :一個同步輔助類,它允許一組執行緒互相等待,直到到達某個公共屏障點
Future :Future 表示非同步計算的結果。
ScheduledExecutorService :一個 ExecutorService,可安排在給定的延遲後執行或定期執行的命令。

一、Executors
Executors工具類是用於建立執行緒池的,可以指定執行緒池的大小(執行緒的數量),也可以不指定大小,也可以指定定時器的執行緒池。下面來一一看看。
1、newFixedThreadPool(固定大小執行緒池)

package sychrionizer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorsTest {
    public static void main(String[] args) {
        //建立了一個5個執行緒的執行緒池 
ExecutorService pool = Executors.newFixedThreadPool(5); for(int i = 0 ; i < 5 ; i++){ //執行執行緒 pool.execute(new MyThread()); } //任務執行完關閉執行緒池 pool.shutdown(); //立即關閉 //pool.shutdownNow(); } } /** * 執行緒 * @author Errol * */
class MyThread implements Runnable{ @Override public void run() { System.out.println("執行緒"+ Thread.currentThread().getName()+"執行中..."); } }

用此方法建立的執行緒池以無界佇列的方式執行這些程式,如果有執行緒過來,就會在一個佇列中等待空閒的執行緒。如果執行緒池關閉前,執行緒執行失敗導致執行緒終止,則將會有一個新的執行緒代替該執行緒,繼續執行剩餘任務。

2、newCachedThreadPool(快取執行緒池)

package sychrionizer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorsTest {
    public static void main(String[] args) {
        //建立的執行緒池 
        ExecutorService pool = Executors.newCachedThreadPool();

        for(int i = 0 ; i < 5 ; i++){
            //執行執行緒
            pool.execute(new MyThread());
        }
        //任務執行完關閉執行緒池
        pool.shutdown();
        //立即關閉
        //pool.shutdownNow();
    }

}
/**
 * 執行緒
 * @author Errol
 *
 */
class MyThread implements Runnable{
    @Override
    public void run() {
        System.out.println("執行緒"+ Thread.currentThread().getName()+"執行中...");
    }
}

什麼是快取執行緒池,說白了,就是執行緒池大小可變的,執行緒池的大小依賴與任務數量,任務數量多,則執行緒池就增大,任務數量少了,則執行緒池將多餘的空閒執行緒關閉掉,達到可變的目的。如上面的程式碼,如果迴圈數量變為10,那麼,則創建出10個執行緒出來。

3、newSingleThreadExecutor()(單個執行緒執行緒池)
程式碼與上面類似,只需要將建立執行緒池的方法改為建立單個執行緒執行緒池。區別在哪呢?
單個執行緒池執行任務,是由一個執行緒執行的,這可以由輸出結果得出該結論。
那單個執行緒執行緒池與我們普通的new Thread()的方式有什麼區別呢?
執行緒池的好處就是,如果該執行緒死了,執行緒池將會重新創建出一個執行緒來執行剩餘的任務。而我們new 的方法中,如果任務失敗了,我們只能重新new一個執行緒出來執行了。

4、newScheduledThreadPool(int corePoolSize)(定時器執行緒池)
我們可以用靜態方法newScheduledThreadPool(int corePoolSize)來定義一個定時器執行緒池,可以指定執行緒個數。然後再呼叫schedule方法,傳進去一個Runnable和定時時長即可。

package sychrionizer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ExecutorsTest {
    public static void main(String[] args) {
        //建立的執行緒池 
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);

        for(int i = 0 ; i < 5 ; i++){
            //執行執行緒
            pool.schedule(new MyThread(), 2, TimeUnit.SECONDS);
        }
        //任務執行完關閉執行緒池
        pool.shutdown();
        //立即關閉
        //pool.shutdownNow();
    }

}
/**
 * 執行緒
 * @author Errol
 *
 */
class MyThread implements Runnable{
    @Override
    public void run() {
        System.out.println("執行緒"+ Thread.currentThread().getName()+"執行中...");
    }
}

上面的程式碼中,建立了一個定時器執行緒池,長度是5,迴圈執行5個任務,且執行緒池在延遲2秒之後開始執行,。
如果需要延遲2秒之後開始執行任務,且,每間隔2秒執行一個任務怎麼辦?
將schedule方法修改為:
pool.scheduleAtFixedRate(new MyThread(), 2, 2, TimeUnit.SECONDS);
即可。