Android中的Semaphore
2016-04-03 16:20
471 查看
信号量,了解过操作系统的人都知道,信号量是用来做什么的···
在Android中,已经提供了Semaphore来帮助我们使用~
那么,在开发中这家伙有什么用呢?
用的地方不多,但是却真的是好用至极!
比如如下代码:
打印出的日志会不一致,如:
这和我们希望见到的num从10打印到0时不相符的。
这里有个坑需要注意一下,比如说这个队列限制只有1个存在,那么在创建时要写0,写1的话,就会变成2个了···以此类推,要队列中有10个对象,需要写9···
在每次acquire后,semaphone将加入一个对象,在不release的情况下,这个对象是会一直存在的。
下面上代码:
日志如下:
这里我们可以很清晰的看到,num从10顺序变为了0。
然后看看日志:
仍然没有问题~~~
下面是全部的代码:
全部代码
在Android中,已经提供了Semaphore来帮助我们使用~
那么,在开发中这家伙有什么用呢?
用的地方不多,但是却真的是好用至极!
#0 举个栗子
我相信很多人在开发中都会遇到这样的事情:当要对一个资源进行多次数据读取并且修改操作时,会遇到执行的速度快慢不一致导致修改值发生改变的情况。比如如下代码:
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时不相符的。
#1 Semaphore的使用
接着上面的代码,我们加入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。
#2 再加点延迟试试
现在,我们再在其中增加一些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
仍然没有问题~~~
#3 需要注意的地方
如果使用了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 Studio打包以及签名
- (源码分析)Android-Universal-Image-Loader (图片异步加载缓存库)的使用配置
- Android SDK 目录下文件夹的含义
- Android学习第五周_SharedPreferences和文件管理
- Android StrictMode 详解
- android系统通过图片绝对路径获取URI的三种方法
- Android仿QQ实现聊天功能
- Android studio最简单的更新方法
- Android设计模式应用---单例模式
- android异步任务处理
- Android 百度地图API 定位 导航
- Xamarin studio for android 与 vs2013 配置android 环境
- android 关于红外控制一点认识。
- android布局中fillparent, wrapconten和matchparent的区别
- Android Studio安装与配置
- Android设计模式之工厂模式 Factory
- JSON介绍及Android最全面解析方法(Gson、AS自带org.son、Jackson解析)
- [android] 调用系统照相机和摄像机
- 4. Android Framework - View的工作原理
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系