編輯:關於Android編程
現在的絕大多數應用程序都是多線程的程序,而當有兩個或兩個以上的線程需要對同一數據進行存取時,就會出現條件競爭,也即
是這幾個線程中都會有一段修改該數據狀態的代碼。但是如果這些線程的運行順序推行不當的話是很容易造成死鎖現象的。所以在JAVA中為
了防止出現這種現象的出現就產生了鎖和條件機制用來對實現各個線程之間互斥的去訪問這段臨界區的代碼,唉!由於我也是才剛學多線程
並發編程,也不可能有多深多深的理解,所以就先只寫一下它們的用法了。
------------------YYC
其實從JAVA SE 5.0以後就有兩種機制來防止代碼塊受並發訪問的干擾,一種是通過lock機制,另一種是通過synchronized來實現,
下面分別來實現。
該部分程序的功能主要是實現通過多個線程 去訪問yy和cc這兩個變量,然後在每個線程中都分別不斷的從其中一個大於0 的變量中減去10,然
後在給另外的一個變量加上10,如果說此處不用鎖的機制去實現線程的修改yy和cc時,是恆容易發生死鎖錯誤的,而且在運行一段時間後yy和cc
的總和也將不再是100.
方法一:
public int yy = 0; public int cc =100;
public class YYThread extends Thread{ private Condition condition ; //定義條件對象 private Lock YYlock = new ReentrantLock(); //定義鎖對象, //其中ReentrantLock()方法是用來構造一個用來保護臨界區的可以重入鎖,此處也可以調用ReentrantLock(boolean fair)來構造一個公平鎖 @Override public void run() { // TODO Auto-generated method stub super.run(); YYlock.lock();//當線程運行到這個地方時給下面的代碼片加上互斥鎖 condition = YYlock.newCondition(); //初始化條件對象 Random random = new Random(); int a = random.nextInt(); int b = a%2; if(b==0) { if(yy<10) {try { condition.await();//當發現該線程的條件不足時,自動阻塞當前線程,並釋放處理機等資源和解鎖臨界資源 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }} yy-=10; cc+=10; Log.d("yy "+yy, "cc "+cc); condition.signalAll();//當資源狀態改變時,調用該方法解除所有因這一條件而等待的所有線程,當這些線程從等待集裡移除時。它們就 //再次成為可運行的,相當於是處於就緒狀態,調度器就可再次激活他們。 } else { if(cc<10) {try { condition.await(); //當發現該線程的條件不足時,自動阻塞當前線程,並釋放處理機等資源和解鎖臨界資源 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }} yy+=10; cc-=10; Log.d("yy "+yy, "cc "+cc); condition.signalAll();//激活其他線程 } try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace();} finally{ YYlock.unlock(); //解鎖對該部分代碼的訪問控制,注意此解鎖操作必須要放在finally字句裡面,因為如果臨界區的代碼拋出異常的話,鎖必須要被 //釋放,否則其他所有線程都將永遠阻塞 } } }
//實現方式一: for(int i =0 ;i<80;i++) { YYThread yt = new YYThread(); yt.start(); }
成功實現鎖和條件的機制鎖主要是原來實現保護臨界區的代碼片,實現互斥的相互訪問
條件主要是用來管理進入臨界區的線程condition.await();進入條件的等待集, 該線程被阻塞,
並自動放棄處理機資源和解鎖臨界資源,但它與互斥阻塞的主要區別是只要
當condition.signalAll();激活該該線程時,該線程將立馬成為可運行的,並接受調度器的調度。
YYlock.lock();互斥阻塞,當獲得臨界資源時才可能被執行
定義該方法
public int yy = 0; public int cc =100; private synchronized void fun()//用關鍵字synchronized聲明為該方法只能互斥訪問 { Random random = new Random(); int a = random.nextInt(); int b = a%2; if(b==0) { while(yy<10) {try { wait();//條件阻塞 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }} yy-=10; cc+=10; notifyAll();//激活阻塞隊列的線程 Log.d("yy "+yy, "cc "+cc); } else { while(cc<10) {try { wait();//用while循環檢測條件,但也會遵循“讓權等待”的原則。 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }} cc-=10; yy+=10; notifyAll();//激活阻塞隊列的線程 Log.d("yy "+yy, "cc "+cc); } }
public class YYThread extends Thread{ @Override public void run() { // TODO Auto-generated method stub super.run(); fun(); } }
for(int i =0 ;i<80;i++) { YYThread yt = new YYThread(); yt.start(); }
其實每一個對象都是有一個內部鎖的,並且該鎖有一個內部條件,由鎖來管理那些試圖進入synchronized方法的線程,由條件來管理那些調用wait的線程。
您應該始終外部化應用資源,例如圖像和代碼中的字符串,這樣有利於您單獨維護這些資源。 此外,您還應該為特定設備配置提供備用資源,方法是將它們分組到專門命名的資源目錄中。 在
信自己也是一種信仰。寫在前面的話3月初我在自定義控件概述中挖下的幾個坑,前一段時間已經基本填完了,自定義控件的幾種實現方式也分別寫了demo來進行說明。今天我們來聊一聊
前幾天因為在省公安廳做一個通訊類之類的應用;碰到個問題,就是download人員信息將信息保存到本地數據庫完成的時候,菊花轉還沒有dismission掉程序就崩潰了;當然
1,使用SharedPrefrences用於簡單少量的數據,數據的格式簡單:都是普通的字符串,標量類型的值等,比如各種配置信息等等SharedPrefrences與Edi
一 概述本文是Android導航分組列表系列上,因時間和篇幅原因分上下,