Java裏面在處理任務,好比和用戶交互的過程當中,不可避免的要用到多線程一遍監聽用戶輸入,一遍處理任務,這時就涉及到併發了。關於併發狀況要考慮的不少,這裏只是簡單記錄一下。
1、線程:
1.在java中線程分爲普通線程和守護線程(也叫後臺線程),普通線程裏面開啓的線程默認爲普通線程,守護線程裏面開啓的線程默認爲守護線程。固然普通線程也能夠設置是否爲守護線程:java
Thread thread=new Thread(runnable); //設置是否爲守護線程 thread.setDaemon(true);
當普通線程都結束時,後臺線程也會忽然都關閉終止,由於此時jvm會關閉全部的後臺進程。
2.在Android裏面主要分爲主線程和子線程。打開APP默認的任務都運行在主線程中,本身開的線程就是子線程。子線程不能更新UI,只能在主線程中更新。
線程能夠在run方法的開頭,設置線程優先級:程序員
public void run() { Thread.currentThread().setPriority(priority); }
不過它只是一個建議,不能保證必定優先級高的先執行,因此在處理多線程時,用這個不太靠譜。
2、多線程:
在開線程處理任務時,Thread thread=new Thread(r);就開了一個線程,當有大量併發任務,要開不少線程時,怎麼處理控制比較好呢?JDK提供了ExecutorService來處理:編程
//建立線程池,默認線程數爲0,當有任務須要執行時,會先查看是否有空閒的可用線程,沒有就建立新的線程 ExecutorService cachedExecutorService = Executors.newCachedThreadPool(); //建立線程池,默認線程數爲3,固定只有3個線程,多餘的任務排隊執行 ExecutorService fixedExecutorService = Executors.newFixedThreadPool(3); //建立線程池,只有一個線程,任務排隊一個一個執行,Executors.newFixedThreadPool(1)同樣 ExecutorService singleExecutorService = Executors.newSingleThreadExecutor(); //使用線程池代替直接new線程去執行Runnable任務 fixedExecutorService.execute(new Runnable() { @Override public void run() { //要執行的任務 } });
3、併發:
多線程的執行時機是不肯定的,以單核CPU爲例,在執行多線程時是CPU在分時間片切換執行線程,致使好像是多線程併發執行。若是是多核多是真正在併發執行,不過這不是重點,重點是:若是一個線程在操做打印機打印東西到一半,這時切換到另外一個線程也在操做這個打印機打印東西,這個時候打印出來的東西就亂套了。怎麼處理這種狀況呢?JDK提供了
1.synchronized關鍵字,就是給上一把鎖,當這個方法被調用時加上一把鎖,等方法執行完返回時釋放鎖。方法執行期間,其它線程來執行該方法時,只能在方法外面等候。多線程
public synchronized void status(){ //同一時間,只能有一個線程執行此方法 try { TimeUnit.MILLISECONDS.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name); }
這個鎖默認是這個對象自己,也可使用synchronized 代碼塊本身換鎖:併發
synchronized (new String("lock")) { //...... }
2.使用volatile 關鍵字來定義變量,能夠得到原子性和可視性,也能夠用來作同步處理。jvm
volatile int data ;
不過這樣作是有風險的,首選仍是synchronized.
3.使用JDK提供的鎖Lock:ide
public void doSomething(){ Lock lock=new ReentrantLock(); lock.lock(); //可能出現多線程同時執行的任務... lock.unlock(); }
4.使用同步隊列BlockingQueue,把須要執行的任務runnable都裝進去,在執行的時候會依次一個個取出來執行。
5.有些容器是自帶鎖,有些是免鎖容器沒有鎖。當在非多線程程序中使用自帶鎖容器時,會致使很大的開銷。
不一樣的方式,在不一樣的環境下性能也不同,最終結果仍是取決於本身的測試。
4、死鎖:
多線程併發,採起同步處理後,可能會引起另外一個問題:死鎖。經典問題是哲學家就餐問題 。
同時知足如下4個條件時,死鎖就會產生:
1.任務使用的資源中是不能共享的 。
2.一個任務持有一個資源,同時在等待另外一個任務持有的資源。
3.資源不能被任務搶奪,是任務本身釋放的。
4.循環等待,即任務1在等待任務2,任務2在等待任務3...任務N-1在等待任務N,任務N在等待任務1。
編程時真正的問題在於,程序看起來在正確運行,但可能潛在死鎖的危險。這就要靠程序員本身來判斷避免死鎖了,good luck。性能