JAVA语言开发中的ReentranLock解析
小标 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
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved