編輯:關於Android編程
為什麼會有線程同步的概念呢?為什麼要同步?什麼是線程同步?先看一段代碼:
package com.maso.test; public class ThreadTest2 implements Runnable{ private TestObj testObj = new TestObj(); public static void main(String[] args) { ThreadTest2 tt = new ThreadTest2(); Thread t1 = new Thread(tt, "thread_1"); Thread t2 = new Thread(tt, "thread_2"); t1.start(); t2.start(); } @Override public void run() { for(int j = 0; j < 10; j++){ int i = fix(1); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " : i = " + i); } } public int fix(int y){ return testObj.fix(y); } public class TestObj{ int x = 10; public int fix(int y){ return x = x - y; } } }輸出結果後,就會發現變量x被兩個線程同時操作,這樣就很容易導致誤操作。如何才能解決這個問題呢?用線程的同步技術,加上synchronized關鍵字
public synchronized int fix(int y){ return testObj.fix(y); }加上同步後,就可以看到有序的從9輸出到-10.
如果加到TestObj類的fix方法上能不能實現同步呢?
public class TestObj{ int x = 10; public synchronized int fix(int y){ return x = x - y; } }如果將synchronized加到方法上則等價於
synchronized(this){ }可以判斷出兩個線程使用的TestObj類的同一個實例testOjb,所以後實現同步,但是輸出的結果卻不是理想的結果。這是因為當A線程執行完x = x - y後還沒有輸出則B線程已經進入開始執行x = x - y.
所以像下面這樣輸出就不會有什麼問題了:
public class TestObj{ public TestObj(){ System.out.println("調用了構造函數"); } int x = 10; public synchronized int fix(int y){ x = x - y; System.out.println(Thread.currentThread().getName() + " : x = " + x); return x; } }如果將外部的fix方法修改如下:
public int fix(int y){ ax++ ; if(ax%2 == 0){ return testObj.fix(y, testObj.str1); }else{ return testObj.fix(y, testObj.str2); } }
public class TestObj{ String str1 = "a1"; String str2 = "a2"; public TestObj(){ System.out.println("調用了構造函數"); } int x = 10; public int fix(int y, String str){ synchronized (str) { x = x - y; System.out.println(Thread.currentThread().getName() + " : x = " + x); } return x; } }此時synchronized中的str對象不是同一個對象,所以兩個線程所持有的對象鎖不是同一個,這樣就不能實現同步。要實現線程之間的互斥就要使用同一個對象鎖。
什麼是死鎖呢?舉個例子就是比如你和同學租了個兩室的房子,你拿著你房子的鑰匙,你同學拿著他房子的鑰匙,現在你在房子等你同學將他的鑰匙給你然後你進他房子,你同學在他的房子等你將鑰匙給他然後他進你的房子,這樣就死鎖了。
package com.maso.test; public class ThreadDieSock implements Runnable { private int flag = 1; private Object obj1 = new Object(), obj2 = new Object(); public void run() { System.out.println("flag=" + flag); if (flag == 1) { synchronized (obj1) { System.out.println("我已經鎖定obj1,休息0.5秒後鎖定obj2去!"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj2) { System.out.println("1"); } } } if (flag == 0) { synchronized (obj2) { System.out.println("我已經鎖定obj2,休息0.5秒後鎖定obj1去!"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj1) { System.out.println("0"); } } } } public static void main(String[] args) { ThreadDieSock run01 = new ThreadDieSock(); ThreadDieSock run02 = new ThreadDieSock(); run01.flag = 1; run02.flag = 0; Thread thread01 = new Thread(run01); Thread thread02 = new Thread(run02); System.out.println("線程開始喽!"); thread01.start(); thread02.start(); } }
前段時間下載了AChartEnginee的源碼,並且對源碼的框架進行了一些了解,講解了整個框架的組成部分和每個部分的作用,最近一周則主要看了一下源碼中的demo部分,即如
Android實際開發中,在加載大量圖片的時候,比如ViewPager、GridView、ListView中,加載了大量的比較大圖片就容易出現OOM(內存溢出)的異常,這
1 智能指針的設計思想 Java和C++語言很重要的一個區別就是Java中沒有指針這個概念,這裡只是沒有這個概念,內部使用時還是用到指針,只是將其
前言:我相信”天生我才必有用”這句話,每個人都有他的作用,也許他的作用相對其他人來不是很明顯,也許他的作用也就是取悅別人,但是請不要忘記,可以通過