啓動線程調用start() 方法,run()方法是線程啓動後須要執行的方法。 1. 繼承thread類 2. 實現runnable 接口 3. 實現callable 接口(call()方法,有返回值經過future對象的get()方法能夠獲取返回值,get()方法會阻塞,直到任務結果返回)
1. Callable規定的方法是call(),而Runnable規定的方法是run()。 2. Callable的任務執行後可返回值,而Runnable的任務是不能返回值的。 3. call()方法可拋出異常,而run()方法是不能拋出異常的。 4. 運行Callable任務可拿到一個Future對象, Future表示異步計算的結果。 5. 它提供了檢查計算是否完成的方法,以等待計算的完成,並檢索計算的結果。 6. 經過Future對象可瞭解任務執行狀況,可取消任務的執行,還可獲取任務執行的結果。 7. Callable是相似於Runnable的接口,實現Callable接口的類和實現Runnable的類都是可被其它線程執行的任務
經常使用的是 ThreadPoolExecutor 類 自定義 corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit, BlockingQueue數據庫
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
線程池公式 :緩存
maximumPoolSize = 2 * corePoolSize = 4 * cpu線程數
Executors.new SingleThreadPoolExecutor(); 最大線程數爲1 Executors.new FixedThreadPoolExecutor(5) :核心線程數 = 最大線程數 Executors.new CachedThreadPoolExecutor() :緩存線程池 Executors.new ScheduledThreadPoolExecutor(5) :延遲/週期性線程池
single和fixed阻塞隊列最大爲 Interger.MAX_VALUE [2的31次方];
cached 和scheduled 最大線程數爲 Interger.MAX_VALUE [2的31次方];多線程
===========================================================================dom
// 獲取鎖 void lock() // 若是當前線程未被中斷,則獲取鎖,能夠響應中斷 void lockInterruptibly() // 返回綁定到此 Lock 實例的新 Condition 實例 Condition newCondition() // 僅在調用時鎖爲空閒狀態才獲取該鎖,能夠響應中斷 boolean tryLock() // 若是鎖在給定的等待時間內空閒,而且當前線程未被中斷,則獲取鎖 boolean tryLock(long time, TimeUnit unit) // 釋放鎖 void unlock()
tryLock()方法是有返回值的,它表示用來嘗試獲取鎖,若是獲取成功,則返回true;若是獲取失敗(即鎖已被其餘線程獲取),則返回false,也就是說,這個方法不管如何都會當即返回(在拿不到鎖時不會一直在那等待)。
tryLock(long time, TimeUnit unit)方法和tryLock()方法是相似的,只不過區別在於這個方法在拿不到鎖時會等待必定的時間,在時間期限以內若是還拿不到鎖,就返回false,同時能夠響應中斷。若是一開始拿到鎖或者在等待期間內拿到了鎖,則返回true。異步
要點 : 共享讀,獨佔寫
//返回用於讀取操做的鎖 Lock readLock() //返回用於寫入操做的鎖 Lock writeLock()
代碼示例 :工具
// 讀數據 public void get() { // 加讀鎖 lock.readLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to read data!"); Thread.sleep((long) (Math.random() * 1000)); System.out.println(Thread.currentThread().getName() + " have read data :" + data); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 釋放讀鎖 lock.readLock().unlock(); } } // 寫數據 public void put(Object data) { // 加寫鎖 lock.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to write data!"); Thread.sleep((long) (Math.random() * 1000)); this.data = data; System.out.println(Thread.currentThread().getName() + " have write data: " + data); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 釋放寫鎖 lock.writeLock().unlock(); } } }