小标
2018-12-19
来源 :
阅读 835
评论 0
摘要:本文主要向大家介绍了JAVA语言开发中的ReentranLock解析,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。
本文主要向大家介绍了JAVA语言开发中的ReentranLock解析,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。
在Java多线程中,可以使用synchronized关键字来实现线程之间的同步互斥,但在JDK1.5中新增加的ReentranLock也能达到同样的效果,并且在扩展功能上也更加强大。
一、使用lock方法和unlock方法实现同步
ReentranLock的lock方法用来获取锁,而调用unlock的方法是释放锁。
public class Test1 {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
ThreadA aa = new ThreadA(service);
aa.setName("AA");
Thread.sleep(100);
ThreadB b = new ThreadB(service);
b.setName("B");
ThreadB bb = new ThreadB(service);
bb.setName("BB");
bb.start();
a.start();
aa.start();
b.start();
}
}
class ThreadA extends Thread{
private Service service;
public ThreadA(Service service){
this.service = service;
}
@Override
public void run() {
service.methodA();
}
}
class ThreadB extends Thread{
private Service service;
public ThreadB(Service service){
this.service = service;
}
@Override
public void run() {
service.methodB();
}
}
class Service{
private ReentrantLock lock = new ReentrantLock();
public void methodA(){
try {
lock.lock();
System.<em>out</em>.println("A ThreadName = "+Thread.currentThread().getName());
Thread.sleep(2000);
System.<em>out</em>.println("A ThreadName = "+Thread.currentThread().getName());
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void methodB(){
try {
lock.lock();
System.<em>out</em>.println("B ThreadName = "+Thread.currentThread().getName());
Thread.sleep(2000);
System.<em>out</em>.println("B ThreadName = "+Thread.currentThread().getName());
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
上述代码使用lock方法和unlock方法实现了线程间的同步。输出结果如下
结果说明,调用lock方法的代码的线程就持有了对象监视器,其他线程只有等待锁被释放时再次争抢,效果和使用sunchronized关键字一样。
二、使用Condition实现等待/通知。
使用synchronized关键字以及wait方法和notify方法相结合可以实现等待/通知模式,而ReentranLock也可以实现同样的功能,但需要借助于Condition对象。
你可以在一个ReentranLock对象里面创建多个Condition实例(对象监视器),线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。
public class Test2 {
public static void main(String[] args) throws InterruptedException {
Service1 service1 = new Service1();
ThreadAA threadAA = new ThreadAA(service1);
threadAA.setName("A");
threadAA.start();
Thread.sleep(1000);
service1.singal();
}
}
class Service1{
private ReentrantLock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await(){
try {
lock.lock();
System.<em>out</em>.println(Thread.currentThread().getName()+"我在等待通知的到来1");
condition.await();
System.<em>out</em>.println(Thread.currentThread().getName()+"等到通知了,我继续执行");
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void singal(){
try {
lock.lock();
System.<em>out</em>.println("我要通知在等待的线程");
condition.signal();
}finally {
lock.unlock();
}
}
}
class ThreadAA extends Thread{
private Service1 service1;
public ThreadAA(Service1 service1){
this.service1 = service1;
}
@Override
public void run() {
service1.await();
}
}
上述代码就描述了Condition的用法,Condition在调用await方法之前必须调用lock方法来获得同步监视器。否则会报错。
而singal方法可以唤醒同一个Condition(对象监视器)监视下的线程。
输出结果如下:
等待一秒后通知
线程继续执行未完的代码。其中wait方法相当于await方法,notify方法相当于singal方法,notifyAll方法相当于singalAll方法。
刚才我们只是使用一个Condition方法通知一个线程,这次我们使用多个Condition通知多个线程。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!
喜欢 | 1
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号