A. java 有沒有比threadpooltaskexecutor更好的多線程工具類
使用SPRING中的線程池ThreadPoolTaskExecutor實現並發。
一:不需要返回值的情況
1,初始化線程池
Java代碼
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
poolTaskExecutor.setQueueCapacity(10000);
poolTaskExecutor.setCorePoolSize(5);
poolTaskExecutor.setMaxPoolSize(10);
poolTaskExecutor.setKeepAliveSeconds(5000);
poolTaskExecutor.initialize();
2,在線程池中執行某個線程
Java代碼
poolTaskExecutor.execute(new Thread(Objct...){...});
二:需要返回值的情況
1,初始化線程池poolTaskExecutor,同上
2,新建一個類,實現Callable介面
Java代碼
class GetFromDB implements Callable<User> {
private UserDao userDao;
private Long userId;
public GetFromDB(UserDao userDao, Long userId) {
this.userDao = userDao;
this.userId = userId;
}
public User call() throws DaoException {
User user = userDao.getUserById(userId);
return user;
}
}
3,用之前的GetFromDB類構造一個FutureTask類
Java代碼
FutureTask<User> dbtask = new FutureTask<User>(GetFromDB);
4,提交並執行
Java代碼
threadpool.submit(dbtask);
5,得到返回值
Java代碼
try {
User user = dbtask.get();
} catch (Exception e) {
if (e instanceof ExecutionException
&& ((ExecutionException) e).getCause() instanceof DaoException) {
throw (DaoException) ((ExecutionException) e).getCause();
} else {
其他處理方式
}
}
註:一旦調用了get()方法,如果線程還未產生返回值,則將阻塞get()方法,直到得到返回值。基於此,如果你想確保線程執行完後才執行下一步操作,即使你不想得到返回值也可以調用一下此方法。當然這與多線程的初衷不符。
B. java多線程有幾種實現方法
繼承Thread類來實現多線程:
當我們自定義的類繼承Thread類後,該類就為一個線程類,該類為一個獨立的執行單元,線程代碼必須編寫在run()方法中,run方法是由Thread類定義,我們自己寫的線程類必須重寫run方法。
run方法中定義的代碼為線程代碼,但run方法不能直接調用,如果直接調用並沒有開啟新的線程而是將run方法交給調用的線程執行
要開啟新的線程需要調用Thread類的start()方法,該方法自動開啟一個新的線程並自動執行run方法中的內容
*java多線程的啟動順序不一定是線程執行的順序,各個線程之間是搶佔CPU資源執行的,所有有可能出現與啟動順序不一致的情況。
CPU的調用策略:
如何使用CPU資源是由操作系統來決定的,但操作系統只能決定CPU的使用策略不能控制實際獲得CPU執行權的程序。
線程執行有兩種方式:
1.搶占式:
目前PC機中使用最多的一種方式,線程搶佔CPU的執行權,當一個線程搶到CPU的資源後並不是一直執行到此線程執行結束,而是執行一個時間片後讓出CPU資源,此時同其他線程再次搶佔CPU資源獲得執行權。
2.輪循式;
每個線程執行固定的時間片後讓出CPU資源,以此循環執行每個線程執行相同的時間片後讓出CPU資源交給下一個線程執行。
C. java並發框架有哪些
Java並發框架java.util.concurrent是JDK5中引入到標准庫中的(採用的是Doug
Lea的並發庫)。該包下的類可以分為這么塊:
Executors
1)介面:
Executor(例子涉及):用來執行提交的Runnable任務的對象。是一個簡單的標准化介面,用來定義包括線程池、非同步IO、輕量級任務框架等等。任務可以由一個新創建的線程、一個已有任務執行線程、或是線程直接調用execute()來執行,可以串列也可並行執行,取決於使用的是哪個Executor具體類。
ExecutorService(例子涉及):Executor的子介面,提供了一個更加具體的非同步任務執行框架:提供了管理結束的方法,以及能夠產生Future以跟蹤非同步任務進程的方法。一個ExcutorService管理著任務隊列和任務調度。
ScheledExecutorService(例子涉及):ExecutorService的子介面,增加了對延遲和定期任務執行的支持。
Callable(例子涉及):一個返回結果或拋出異常的任務,實現類需要實現其中一個沒有參數的叫做call的方法。Callabe類似於Runnable,但是Runnable不返回結果且不能拋出checked
exception。ExecutorService提供了安排Callable非同步執行的方法。
Future(例子涉及):代表一個非同步計算的結果(由於是並發執行,結果可以在一段時間後才計算完成,其名字可能也就是代表這個意思吧),提供了可判斷執行是否完成以及取消執行的方法。
2)實現:
ThreadPoolExecutor和ScheledThreadPoolExecutor:可配置線程池(後者具備延遲或定期調度功能)。
Executors(例子涉及):提供Executor、ExecutorService、ScheledExecutorService、ThreadFactory以及Callable的工廠方法及工具方法。
FutureTask:對Future的實現
ExecutorCompletionService(例子涉及):幫助協調若干(成組)非同步任務的處理。
Queues
非阻塞隊列:ConcurrentLinkedQueue類提供了一個高效可伸縮線程安全非阻塞FIFO隊列。
阻塞隊列:BlockingQueue介面,有五個實現類:LinkedBlockingQueue(例子涉及)、ArrayBlockingQueue、SynchronousQueue、PriorityBlockingQueue和DelayQueue。他們對應了不同的應用環境:生產者/消費者、消息發送、並發任務、以及相關並發設計。
Timing
TimeUnit類(例子涉及):提供了多種時間粒度(包括納秒)用以表述和控制基於超時的操作。
Synchronizers 提供特定用途同步語境
Semaphore(例子涉及):計數信號量,這是一種經典的並發工具。
CountDownLatch(例子涉及):簡單的倒計數同步工具,可以讓一個或多個線程等待直到另外一些線程中的一組操作處理完成。
CyclicBarrier(例子涉及):可重置的多路同步工具,可重復使用(CountDownLatch是不能重復使用的)。
Exchanger:允許兩個線程在匯合點交換對象,在一些pipeline設計中非常有用。
Concurrent Collections
除隊列外,該包還提供了一些為多線程上下文設計的集合實現:ConcurrentHashMap、CopyOnWriteArrayList及CopyOnWriteArraySet。
注意:"Concurrent"前綴的類有別於"synchronized"前綴的類。「concurrent」集合是線程安全的,不需要由單排斥鎖控制的(無鎖的)。以ConcurrentHashMap為例,允許任何數量的並發讀及可調數量的並發寫。「Synchronized」類則一般通過一個單鎖來防止對集合的所有訪問,開銷大且伸縮性差。