編輯:Android編程入門
信號量,了解過操作系統的人都知道,信號量是用來做什麼的···
在Android中,已經提供了Semaphore來幫助我們使用~
那麼,在開發中這家伙有什麼用呢?
用的地方不多,但是卻真的是好用至極!
我相信很多人在開發中都會遇到這樣的事情:當要對一個資源進行多次數據讀取並且修改操作時,會遇到執行的速度快慢不一致導致修改值發生改變的情況。
比如如下代碼:
private void Start() { for (int i = 10; i >= 0; i--) { LogString = "num:" + i; printLogString(i); } } private void printLogString(final int delayTime) { Log.e("TAG", "Runnable" + delayTime); new Thread(new Runnable() { @Override public void run() { Log.e("TAG", LogString); } }).start(); }
打印出的日志會不一致,如:
04-03 15:33:07.294 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable10 04-03 15:33:07.296 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable9 04-03 15:33:07.296 17078-17777/com.gao.luna.semaphoretest E/TAG: num:9 04-03 15:33:07.297 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable8 04-03 15:33:07.297 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable7 04-03 15:33:07.298 17078-17778/com.gao.luna.semaphoretest E/TAG: num:7 04-03 15:33:07.299 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable6 04-03 15:33:07.299 17078-17779/com.gao.luna.semaphoretest E/TAG: num:6 04-03 15:33:07.300 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable5 04-03 15:33:07.301 17078-17780/com.gao.luna.semaphoretest E/TAG: num:5 04-03 15:33:07.301 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable4 04-03 15:33:07.302 17078-17781/com.gao.luna.semaphoretest E/TAG: num:4 04-03 15:33:07.303 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable3 04-03 15:33:07.303 17078-17782/com.gao.luna.semaphoretest E/TAG: num:3 04-03 15:33:07.304 17078-17783/com.gao.luna.semaphoretest E/TAG: num:3 04-03 15:33:07.305 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable2 04-03 15:33:07.305 17078-17784/com.gao.luna.semaphoretest E/TAG: num:2 04-03 15:33:07.305 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable1 04-03 15:33:07.306 17078-17078/com.gao.luna.semaphoretest E/TAG: Runnable0 04-03 15:33:07.306 17078-17785/com.gao.luna.semaphoretest E/TAG: num:0 04-03 15:33:07.308 17078-17786/com.gao.luna.semaphoretest E/TAG: num:0 04-03 15:33:07.308 17078-17787/com.gao.luna.semaphoretest E/TAG: num:0
這和我們希望見到的num從10打印到0時不相符的。
接著上面的代碼,我們加入Semaphore來解決這個問題:
private final Semaphore semaphore = new Semaphore(0, true);
這裡有個坑需要注意一下,比如說這個隊列限制只有1個存在,那麼在創建時要寫0,寫1的話,就會變成2個了···以此類推,要隊列中有10個對象,需要寫9···
在每次acquire後,semaphone將加入一個對象,在不release的情況下,這個對象是會一直存在的。
下面上代碼:
private final Semaphore semaphore = new Semaphore(0, true); private void Start() { for (int i = 10; i >= 0; i--) { try { Log.e("Semaphore", "semaphore.acquire();" + i); semaphore.acquire(); } catch (Exception ex) { Log.e("Semaphore", ex.getMessage()); } LogString = "num:" + i; printLogString(i); } } private void printLogString(final int delayTime) { new Thread(new Runnable() { @Override public void run() { Log.e("Semaphore", "semaphore.release();"); Log.e("TAG", LogString); semaphore.release(); } }).start(); }
日志如下:
04-03 15:40:41.060 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.065 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();10 04-03 15:40:41.078 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();9 04-03 15:40:41.078 26200-26513/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.084 26200-26513/com.gao.luna.semaphoretest E/TAG: num:10 04-03 15:40:41.086 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();8 04-03 15:40:41.086 26200-26514/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.086 26200-26514/com.gao.luna.semaphoretest E/TAG: num:9 04-03 15:40:41.086 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();7 04-03 15:40:41.087 26200-26515/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.087 26200-26515/com.gao.luna.semaphoretest E/TAG: num:8 04-03 15:40:41.087 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();6 04-03 15:40:41.088 26200-26516/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.088 26200-26516/com.gao.luna.semaphoretest E/TAG: num:7 04-03 15:40:41.088 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();5 04-03 15:40:41.088 26200-26517/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.088 26200-26517/com.gao.luna.semaphoretest E/TAG: num:6 04-03 15:40:41.089 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();4 04-03 15:40:41.089 26200-26518/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.089 26200-26518/com.gao.luna.semaphoretest E/TAG: num:5 04-03 15:40:41.090 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();3 04-03 15:40:41.090 26200-26519/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.091 26200-26519/com.gao.luna.semaphoretest E/TAG: num:4 04-03 15:40:41.091 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();2 04-03 15:40:41.092 26200-26520/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.092 26200-26520/com.gao.luna.semaphoretest E/TAG: num:3 04-03 15:40:41.092 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();1 04-03 15:40:41.093 26200-26521/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.093 26200-26521/com.gao.luna.semaphoretest E/TAG: num:2 04-03 15:40:41.094 26200-26200/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();0 04-03 15:40:41.094 26200-26522/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.094 26200-26522/com.gao.luna.semaphoretest E/TAG: num:1 04-03 15:40:41.095 26200-26523/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 15:40:41.095 26200-26523/com.gao.luna.semaphoretest E/TAG: num:0
這裡我們可以很清晰的看到,num從10順序變為了0。
現在,我們再在其中增加一些sleep代碼,再來測試看看。
private final Semaphore semaphore = new Semaphore(0, true); private void Start() { for (int i = 10; i >= 0; i--) { try { Log.e("Semaphore", "semaphore.acquire();" + i); semaphore.acquire(); } catch (Exception ex) { Log.e("Semaphore", ex.getMessage()); } LogString = "num:" + i; printLogString(i); } } private void printLogString(final int delayTime) { Log.e("TAG", "Runnable" + delayTime); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(delayTime * 10); } catch (Exception ex) { Log.e("delayTime", ex.getMessage()); } Log.e("Semaphore", "semaphore.release();"); Log.e("TAG", LogString); semaphore.release(); } }).start(); }
然後看看日志:
04-03 16:15:34.028 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.028 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();10 04-03 16:15:34.028 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable10 04-03 16:15:34.029 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();9 04-03 16:15:34.129 18148-18230/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.129 18148-18230/com.gao.luna.semaphoretest E/TAG: num:10 04-03 16:15:34.130 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable9 04-03 16:15:34.130 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();8 04-03 16:15:34.221 18148-18232/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.221 18148-18232/com.gao.luna.semaphoretest E/TAG: num:9 04-03 16:15:34.221 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable8 04-03 16:15:34.222 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();7 04-03 16:15:34.302 18148-18245/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.302 18148-18245/com.gao.luna.semaphoretest E/TAG: num:8 04-03 16:15:34.303 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable7 04-03 16:15:34.382 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();6 04-03 16:15:34.453 18148-18251/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.453 18148-18251/com.gao.luna.semaphoretest E/TAG: num:7 04-03 16:15:34.453 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable6 04-03 16:15:34.462 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();5 04-03 16:15:34.523 18148-18266/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.523 18148-18266/com.gao.luna.semaphoretest E/TAG: num:6 04-03 16:15:34.523 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable5 04-03 16:15:34.529 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();4 04-03 16:15:34.579 18148-18267/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.579 18148-18267/com.gao.luna.semaphoretest E/TAG: num:5 04-03 16:15:34.579 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable4 04-03 16:15:34.635 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();3 04-03 16:15:34.675 18148-18268/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.675 18148-18268/com.gao.luna.semaphoretest E/TAG: num:4 04-03 16:15:34.675 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable3 04-03 16:15:34.676 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();2 04-03 16:15:34.706 18148-18272/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.706 18148-18272/com.gao.luna.semaphoretest E/TAG: num:3 04-03 16:15:34.706 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable2 04-03 16:15:34.733 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();1 04-03 16:15:34.753 18148-18275/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.753 18148-18275/com.gao.luna.semaphoretest E/TAG: num:2 04-03 16:15:34.753 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable1 04-03 16:15:34.754 18148-18148/com.gao.luna.semaphoretest E/Semaphore: semaphore.acquire();0 04-03 16:15:34.764 18148-18280/com.gao.luna.semaphoretest E/Semaphore: semaphore.release(); 04-03 16:15:34.764 18148-18280/com.gao.luna.semaphoretest E/TAG: num:1 04-03 16:15:34.764 18148-18148/com.gao.luna.semaphoretest E/TAG: Runnable0 04-03 16:15:34.765 18148-18281/com.gao.luna.semaphoretest E/Semaphore: semaphore.release();
04-03 16:15:34.765 18148-18281/com.gao.luna.semaphoretest E/TAG: num:0
仍然沒有問題~~~
如果使用了Handler,需要注意的是,Handler會返回主線程來進行調用,如果在Handler未執行時在acquire地方暫停了,那麼Handler是不會執行的。需要特別留意。
下面是全部的代碼:
package com.gao.luna.semaphoretest; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.View; import java.util.concurrent.Semaphore; public class MainActivity extends AppCompatActivity { private String LogString; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(onClickListener); } View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { Log.e("Semaphore", "semaphore.release();"); semaphore.release(); Start(); } }; private final Semaphore semaphore = new Semaphore(0, true); private void Start() { for (int i = 10; i >= 0; i--) { try { Log.e("Semaphore", "semaphore.acquire();" + i); semaphore.acquire(); } catch (Exception ex) { Log.e("Semaphore", ex.getMessage()); } LogString = "num:" + i; printLogString(i); } } private void printLogString(final int delayTime) { Log.e("TAG", "Runnable" + delayTime); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(delayTime * 10); } catch (Exception ex) { Log.e("delayTime", ex.getMessage()); } Log.e("Semaphore", "semaphore.release();"); Log.e("TAG", LogString); semaphore.release(); } }).start(); } }全部代碼
Android 碎片(Fragment)碎片是活動的一部分,是的活動更加的模塊化設計。我們可以任務碎片是一種子活動。下面是關於碎片的重要知識點 -碎片擁有
一、ArrayAdapter 只顯示文字activitylistview_layout.xml<?xml version=1.0 encoding=utf-8?&g
這個月裝逼有點少了,為什麼呢,因為去考軟件射雞師了,快到兒童節了,趕緊寫篇博紀念一下逝去的青春,唔,請忽略這句話。 二維碼其實有很多種,但是我們常見的微信使用的
1. 輪播控件的組成部分 我們以知乎日報Android客戶端的輪播控件為例,分析一下輪播控件的主要組成: &