Android多线程之同步锁的使用
本文主要介绍了android多线程之同步锁的使用,分享给大家,具体如下:
一、同步机制关键字synchronized
对于java来说,最常用的同步机制就是synchronized关键字,他是一种基于语言的粗略锁,能够作用于对象、函数、class。每个对象都只有一个锁,谁能够拿到这个锁谁就有访问权限。当synchronized作用于函数时,实际上锁的也是对象,锁定的对象就是该函数所在类的对象。而synchronized作用于class时则是锁的这个class类,并非具体对象。
public class synchronizedclass { public synchronized void syncmethod(){ //代码 } public void syncthis(){ synchronized (this){ //代码 } } public void syncclassmethod(){ synchronized (synchronizedclass.class){ //代码 } } public synchronized static void syncstaticmethod(){ //代码 } }
上面演示了同步方法、同步块、同步class对象、同步静态方法。前2种锁的是对象,而后两种锁的是class对象。对于class对象来说,它的作用是防止多个线程同时访问添加了synchronized锁的代码块,而synchronized作用于引用对象是防止其他线程访问同一个对象中synchronized代码块或者函数。
二、显示锁———-reentranklock和condition
reentranklock 和内置锁synchronized相比,实现了相同的语义,但是更具有更高的灵活性。
(1)获得和释放的灵活性。
(2)轮训锁和定时锁。
(3)公平性。
基本操作:
lock(): 获取锁
trylock(): 尝试获取锁
trylock(long timeout,timeunit unit): 尝试获取锁,如果到了指定的时间还获取不到,那么超时。
unlock(): 释放锁
newcondition(): 获取锁的 condition
使用reentrantlock的一般组合是 lock、trylock、与unlock成对出现,需要注意的是,千万不要忘记调用unlock来释放锁,负责可能引发死锁的问题。reentrantlock的常用形式如下所示:
public class reentrantlockdemo { lock lock = new reentrantlock(); public void dosth(){ lock.lock(); try { //执行某些操作 }finally { lock.unlock(); } } }
需要注意的是,lock必须在finally开中释放,否则,如果受保护的代码抛出异常,锁就可能永远得不到释放!!
reentrantlock类中还有一个重要的函数newcondition(),该函数用户获取lock()上的一个条件,也就是说condition与lock绑定。condition用于实现线程间的通信,他是为了解决object.wait(),nofity(),nofityall() 难以使用的问题。
condition的方法如下:
await() : 线程等待
await(int time,timeunit unit) 线程等待特定的时间,超过的时间则为超时。
signal() 随机唤醒某个等待线程
signal() 唤醒所有等待中的线程
示例代码:
public class myarrayblockingqueue<t> { // 数据数组 private final t[] items; private final lock lock = new reentrantlock(); private condition notfull = lock.newcondition(); private condition notempty = lock.newcondition() ; // 头部索引 private int head; // 尾部索引 private int tail ; // 数据的个数 private int count; public myarrayblockingqueue(int maxsize) { items = (t[]) new object[maxsize]; } public myarrayblockingqueue(){ this(10); } public void put(t t){ lock.lock(); try { while(count == getcapacity()){ system.out.println("数据已满,等待"); notfull.await(); } items[tail] =t ; if(++tail ==getcapacity()){ tail = 0; } ++count; notempty.signalall();//唤醒等待数据的线程 } catch (interruptedexception e) { e.printstacktrace(); }finally { lock.unlock(); } } public int getcapacity(){ return items.length ; } public t take(){ lock.lock(); try { while(count ==0){ system.out.println("还没有数据,等待"); //哪个线程调用await()则阻塞哪个线程 notempty.await(); } t ret = items[head]; items[head] = null ; if(++head == getcapacity()){ head =0 ; } --count; notfull.signalall(); return ret ; } catch (interruptedexception e) { e.printstacktrace(); }finally { lock.unlock(); } return null ; } public int size(){ lock.lock(); try { return count; }finally { lock.unlock(); } } public static void main(string[] args){ myarrayblockingqueue<integer> aqueue = new myarrayblockingqueue<>(); aqueue.put(3); aqueue.put(24); for(int i=0;i<5;i++){ system.out.println(aqueue.take()); } system.out.println("结束"); } }
执行结果:
3
24
还没有数据,等待
三、信号量 semaphore
semaphore是一个计数信号量,它的本质是一个“共享锁”。信号量维护了一个信号量许可集,线程可以通过调用acquire()来获取信号量的许可。当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到可用的许可为止。线程可以通过release()来释放它所持有的信号量许可。
示例:
public class semaphoretest { public static void main(string[] args){ final executorservice executorservice = executors.newfixedthreadpool(3); final semaphore semaphore = new semaphore(3); list<future> futures = new arraylist<>(); for (int i = 0; i < 5; i++) { future<?> submit = executorservice.submit(new runnable() { @override public void run() { try { semaphore.acquire(); system.out.println(" 剩余许可: " + semaphore.availablepermits()); thread.sleep(3000); semaphore.release(); } catch (interruptedexception e) { e.printstacktrace(); } } }); futures.add(submit); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Android开发之自带下载器DownloadManager的使用示例代码
-
Android多线程处理机制中的Handler使用介绍
-
Android开发之瀑布流控件的实现与使用方法示例
-
android开发之调用手机的摄像头使用MediaRecorder录像并播放
-
android应用开发之spinner控件的简单使用
-
Android ListView之EfficientAdapte的使用详解
-
Android 数据存储之 FileInputStream 工具类及FileInputStream类的使用
-
Android 自动判断是电话,网址,EMAIL方法之Linkify的使用
-
Android开发之OkHttpUtils的具体使用方法
-
Android开发之XML文件解析的使用