使用ReentrantLock实现线程同步
来源:互联网 发布:seo综合查询 编辑:程序博客网 时间:2024/05/22 15:15
在Java多线程中,可以使用synchronized关键字来实现线程之间同步互斥,但在JDK1.5中新增了ReentrantLock类也能达到同样的效果,并且在扩展功能上也更加强大,比如有嗅探锁定、多路分支通知等功能,而且在使用上也比synchronized更加灵活。
下面以一个例子来说明ReentrantLock的使用。
首先是Service类,需要被同步的类。
import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class MyService { private Lock lock = new ReentrantLock(); //持有锁变量 public void testMethod(){ lock.lock(); //在方法内部,第一行加锁 for (int i=0;i<5;i++){ System.out.println("Thread name:"+Thread.currentThread().getName()+" "+(i+1)); } lock.unlock(); //处理完成之后解锁 }}
线程类与测试类MyThread,创建4个线程,每个线程用同一个Service对象初始化,线程的run方法即执行service的testMethod方法。
public class MyThread extends Thread{ private MyService service; public MyThread(MyService service){ super(); this.service = service; } @Override public void run(){ service.testMethod(); } public static void main(String[] args){ MyService service = new MyService(); MyThread t1 = new MyThread(service); MyThread t2 = new MyThread(service); MyThread t3 = new MyThread(service); MyThread t4 = new MyThread(service); t1.start();t2.start();t3.start();t4.start(); }}
程序输出如下,可以看到各个线程之间是同步执行的,一个线程执行完释放锁之后,另一个线程才能执行:
Thread name:Thread-1 1Thread name:Thread-1 2Thread name:Thread-1 3Thread name:Thread-1 4Thread name:Thread-1 5Thread name:Thread-2 1Thread name:Thread-2 2Thread name:Thread-2 3Thread name:Thread-2 4Thread name:Thread-2 5Thread name:Thread-0 1Thread name:Thread-0 2Thread name:Thread-0 3Thread name:Thread-0 4Thread name:Thread-0 5Thread name:Thread-3 1Thread name:Thread-3 2Thread name:Thread-3 3Thread name:Thread-3 4Thread name:Thread-3 5
另外,当Service类多个方法(比如A、B方法)内部都调用了lock.lock()进行锁定时,当一个线程在方法A中时,另一个线程不能执行B方法。也就是说lock跟synchronized方法一样,调用lock.lock()的线程持有的是“对象锁”(对象监视器)。同一个时刻,只能有一个线程获得对象锁。
关于Lock其他使用如下:
1、公平性与不公平性
锁Lock分为“公平锁”与“不公平锁”,公平锁表示线程获取锁的顺序是按照线程加锁的顺序分配的,机先来先得的FIFO顺序。而不公平锁就是一种获取锁的抢占机制,是随机获得锁的,和公平锁不一样的就是先来的不一定先得到锁。
在锁的构造函数中有一个如下:
//创建一个具有给定公平策略的 ReentrantLock。ReentrantLock(boolean fair)
2、方法getHoldCount()
方法getHoldCount()的作用是查询当前线程保持此锁定的个数,也就是调用lock()方法的次数。使用方法为:
try{ lock.lock(); System.out.println(lock.getHoldCount()); serviceMethod();}finally{ lock.unlock();}
3、方法getQueueLength()的作用是返回正等待获取此锁定的线程估计数。
4、方法getWaitQueueLength(Condition condition)的作用是返回等待此锁定相关的给定条件Condition的线程估计数,比如有5个线程,每个线程都执行了同一个condition对象的await()方法,则调用getWaitQueueLength(Condition)方法时返回的int值是5.
5、方法lockInterruptibly()的作用是:如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常
方法boolean tryLock()的作用是,仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定。
方法boolean tryLock(long timeout,TimeUnit unit)的作用是,如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定。
参考《Java多线程编程核心技术》
lock 必须在 finally 块中释放。否则,如果受保护的代码将抛出异常,锁就有可能永远得不到释放!这一点区别看起来可能没什么,但是实际上,它极为重要。忘记在 finally 块中释放锁,可能会在程序中留下一个定时炸弹,当有一天炸弹爆炸时,您要花费很大力气才有找到源头在哪。而使用同步,JVM 将确保锁会获得自动释放。
参考:Java 理论与实践: JDK 5.0 中更灵活、更具可伸缩性的锁定机制http://www.ibm.com/developerworks/cn/java/j-jtp10264/index.html
2016.8.9读《实战java高并发程序设计》添加:
1. ReentrantLock称为“可重入锁”,是因为一个线程可以获得多次锁,每次获取锁时都将引用计数增加1。
2. ReentrantLock有个方法lockInterruptibly(),这个方法获取锁,并且自带了相应中断的能力.
3. 重入锁可以使用trylock方法,非阻塞的尝试获取锁。
4. 重入锁有构造方法public ReentrantLock(boolean fair)
可以保证线程获取锁时的公平性,但是性能有影响。
5. ReadWriteLock也应该算是一个优点吧。
- 使用ReentrantLock实现线程同步
- 使用ReentrantLock实现线程同步
- 【Java基础之线程同步(三)】使用ReentrantLock Condition实现线程同步
- ReentrantLock使用Condition实现通知部分线程
- ReentrantLock使用Condition实现通知部分线程
- ReentrantLock实现同步
- Java:多线程,线程同步,同步锁(Lock)的使用(ReentrantLock、ReentrantReadWriteLock)
- java 线程同步中的对象锁 ReentrantLock
- 线程同步ReentrantLock,condition(await,signal)
- 使用信号实现线程同步
- 银行取款[多线程]{使用重入锁Lock接口ReentrantLock锁确保线程同步}
- 4.1.1ReentrantLock实现同步,测试1
- 4.1.1ReentrantLock实现同步,测试2
- ReentrantLock同步
- 线程锁ReentrantLock和Condition的使用
- 线程同步的方法:sychronized、lock、reentrantLock等总结分析
- 线程同步方法、性能比较(synchronized,ReentrantLock,Atomic)
- Java线程之锁对象高效同步(ReentrantLock/ReentrantReadWriteLock)
- [BZOJ2154]Crash的数字表格(莫比乌斯反演)
- 【Python学习笔记】 lambda表达式学习
- 44-Count and Say
- HDU-ACM2032--杨辉三角
- CentOS 7.x PhpMyAdmin Install and Configure with Nginx
- 使用ReentrantLock实现线程同步
- makefile中的赋值
- 袁腾飞——殷商六百年
- C++连接数据库一
- CoreThink主题开发(六)使用H-ui开发博客主题之首页友情链接标签混排
- HDU-ACM2033
- C语言里的库函数(持续更新)
- 卡片布局(CardLayout)
- Java中String