在我們開發的過程中常常會碰到多執行緒的問題,對於多執行緒的實現方式主要有兩種:實現runnable介面、繼承thread類。對於這兩種多執行緒的實現方式也是有著一些差異。既然實現了多執行緒那必然離不開管理這些執行緒,當問題比簡單時乙個或者幾個執行緒就ok了,也涉及不到效率問題。一旦執行緒數量多起來的時候,必然躲不過這些執行緒的建立與銷毀,而往往這是很浪費時間的。這時就需要利用執行緒池來進行管理,既免去了我們建立執行緒和銷毀執行緒的**,也提高了程式的效率。下面針對以上問題做出相關講解。
首先闡述實現runnable的好處:
下面來通過具體**來解釋上述優點,網上很流行的買票系統,假設有10張票,首先通thread來進行購買。**如下:
public
class
ticketthread
extends
thread catch (interruptedexception e) }}
}}
public
static
void
main(string arg)
}
輸出:
執行緒1賣票—->10
執行緒1賣票—->9
執行緒1賣票—->8
執行緒2賣票—->7
執行緒2賣票—->6
執行緒1賣票—->5
執行緒1賣票—->4
執行緒2賣票—->3
執行緒2賣票—->2
執行緒1賣票—->1
實現runnable介面:
package threadtest;
public
class
ticketrunnable
implements
runnable catch (exception e) }}
}}
public
static
void
main(string arg)
}
輸出:
執行緒1賣票—->10
執行緒1賣票—->9
執行緒1賣票—->8
執行緒1賣票—->7
執行緒2賣票—->6
執行緒2賣票—->5
執行緒2賣票—->4
執行緒2賣票—->3
執行緒2賣票—->2
執行緒2賣票—->1
從這兩個例子可以看出,thread也可以資源共享啊,為什麼呢,因為thread本來就是實現了runnable,包含runnable的功能是很正常的啊!!至於兩者的真正區別最主要的就是乙個是繼承,乙個是實現;其他還有一些物件導向的思想,runnable就相當於乙個作業,而thread才是真正的處理執行緒,我們需要的只是定義這個作業,然後將作業交給執行緒去處理,這樣就達到了松耦合,也符合物件導向裡面組合的使用,另外也節省了函式開銷,繼承thread的同時,不僅擁有了作業的方法run(),還繼承了其他所有的方法。綜合來看,用runnable比thread好的多。
針對本例再補充一點,在以上程式中,如果去掉同步**塊,則會出現其中一人購買第0張票的情況,所以我們在做多執行緒並行的時候一定要時刻考慮到邊界值的問題,在關鍵**處必須要做好同步處理。
建立執行緒池主要有三個靜態方法供我們使用,由executors來進行建立相應的執行緒池:
public
static executorsevice newsinglethreadexecutor()
public
static executorsevice newfixedthreadpool(int nthreads)
public
static executorsevice newcachedthreadpool()
public
static scheduledexecutorservice newscheduledthreadpool(int corepoolsize)
我們只需要把實現了runnable的類的物件例項放入執行緒池,那麼執行緒池就自動維護執行緒的啟動、執行、銷毀。我們不需要自行呼叫start()方法來開啟這個執行緒。執行緒放入執行緒池之後會處於等待狀態直到有足夠空間時會喚醒這個執行緒。
private executorservice threadpool = executors.newfixedthreadpool(5);
threadpool.execute(socketthread);
//至少維護5個執行緒容量的空間
private scheduledexecutorservice threadpool = executors.newscheduledthreadpool(5);
//第乙個時間引數表示初始化執行延遲1000毫秒,第二個時間引數表示每隔1000毫秒執行一次
//第二個執行緒必須等到第乙個執行緒執行完成才能繼續執行,儘管時間間隔小於執行緒執行時間
threadpool.scheduleatfixedrate(socketthread, 1000, 1000, timeunit.milliseconds);
threadpool.schedulewithfixeddelay(socketthread, 1000, 1000, timeunit.milliseconds);
//執行緒池不接收新加的執行緒,但是執行完執行緒池內部的所有執行緒
threadpool.shutdown();
//立即關閉執行緒池,停止執行緒池內還未執行的執行緒並且返回乙個未執行的執行緒池列表
threadpool.shutdownnow();
JAVA多執行緒之 執行緒池
執行緒池顧名思義,就是乙個放置執行緒的池子。就跟資料庫連線池差不多。執行緒池通過對併發執行緒的控制,能有效的節省系統資源的浪費,提高系統的效能。學習執行緒池,先了解一下執行緒池的乙個基本結構 executor是乙個介面,其中只有乙個方法,就是execute方法。所以executor實際就是乙個執行緒...
Java多執行緒之執行緒安全
當多個執行緒訪問某乙個類 物件或方法時 這個類始終都能表現出正確的行為,那麼這個類 物件或方法 就是執行緒安全的。public class mythread extends thread public static void main string args 結果如下 t1正在執行 4 t1正在執行...
java 多執行緒 之 Excutor
excutor介面 提供了一種將任務提交和任務執行機制相分離的方法 excutorservice介面 提供了excutor的管理介面,以及可為跟蹤乙個或多個非同步任務狀態而生成future的方法 scheduledexcutorservice介面 提供了可以安排在給定的延遲後執行或定時執行的命令 方...