前段時間有個需求在springmvc mapping的url跳轉前完成一個統計的業務。顯然需要進行非同步處理,不然出錯或者異常會影響到後面的網頁跳轉。非同步方式也就是非阻塞式的,當非同步呼叫成功與否程式會接著往下執行,不必等到輸入輸出處理完畢才返回。
主要用到httpasyncclient-4.0.1.jar,httpclient-4.3.2.jar,httpcore-4.3.2.jar,httpcore-nio-4.3.2.jar,commons-logging-1.1.3.jar。
java.util.concurrent中主要包括三類工具,Executor Freamework,並發集合(Concurrent Collection),以及同步器(Synchronizer)。下面的例子是利用java.util.concurrent.Future只請求一個url非同步請求。Future介面表示非同步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,並擷取計算的結果。計算完成後只能使用 get 方法來擷取結果,如有必要,計算完成前可以阻塞此方法。取消則由 cancel 方法來執行。還提供了其他方法,以確定任務是正常完成還是被取消了。一旦計算完成,就不能再取消計算。如果為了可取消性而使用 Future 但又不提供可用的結果,則可以聲明 Future<?> 形式類型、並返回 null 作為底層任務的結果。
同步器(Synchronizer)是一些使線程能夠等待另一個線程的對象,允許它們協作,最常用的同步器是CountDownLatch和Semaphore。較不常用的是CyclicBarrier和Exchanger。Semaphore類是一個計數訊號量。從概念上講,訊號量維護了一個許可集。如有必要,在許可可用前會阻塞每一個 acquire(),然後再擷取該許可。每個 release() 添加一個許可,從而可能釋放一個正在阻塞的擷取者。但是,不使用實際的許可對象,Semaphore 只對可用許可的號碼進行計數,並採取相應的行動。 CountDownLatch是一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。用給定的計數 初始化 CountDownLatch。由於調用了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之後,會釋放所有等待的線程,await 的所有後續調用都將立即返回。這種現象只出現一次——計數無法被重設。如果需要重設計數,可使用 CyclicBarrier。倒計數索存器(CountDownLatch)是一次性的障礙。它的唯一構造器帶有一個int類型的參數,這個參數是指允許所有的等待線程處理之前,必須在鎖存器上調用countDown()方法的次數。這一點非常有用。下面是非同步請求一組url的例子,利用callback借口完成獨立的操作。