课程咨询 :18487146383

  • Java同步方法的使用问题

    发布:张_逸      来源:简书      时间:2016-09-27

  • Release It!的作者对Java中同步方法的使用也提出了警告。同步方法虽然可以较好地解决并发问题,在一定程度上可以避免出现资源抢占、竟态条件和死锁的情况。达内长沙java培训要提醒各位的是,它的一个副作用同步锁可能导致线程阻塞。这就要求同步方法的执行时间不能太长。此外,Java的接口方法是不能标记synchronized关键字。当我们在调用封装好的第三方API时,基于“面向接口设计”的原理,可能调用者只知道公开的接口方法,却不知道实现类事实上将其实现为同步方法,这种未知性就可能存在隐患。

    假设有这样的一个接口:

    public interface GlobalObjectCache {

    public Object get(String id);

    }

    如果接口方法get()的实现如下:

    public synchronized Object get(String id){

    Object obj = items.get(id);

    if(obj == null) {

    obj = create(id);

    items.put(id, obj);

    }

    return obj;

    }

    protected Object create(String id) {

    //...

    }

    这段代码很简单,当调用者试图根据id获得目标对象时,首先会在Cache中寻找,如果有就直接返回;否则通过create()方法获得目标对象,然后再将它存储到Cache中。create()方法是该类定义的一个非final方法,它执行了DB的查询功能。现在,假设使用该类的用户对它进行了扩展,例如定义RemoteAvailabilityCache类派生该类,并重写create()方法,将原来的本地调用改为远程调用。问题出现了。由于采用create()方法是远程调用,当服务端比较繁忙时,发出的远程调用请求可能会被阻塞。由于get()方法是同步方法,在方法体内,每次只能有一个线程访问它,直到方法执行完毕释放锁。现在create()方法被阻塞,就会导致其他试图调用RemoteAvailabilityCache对象的get()方法的线程随之而被阻塞。进而可能导致系统崩溃。

    当然,我们可以认为这种扩展本身是不合理的。但从设计的角度来看,它并没有违背Liskove替换原则。从接口的角度看,它的行为也没有发生任何改变,仅仅是实现发生了变化。如果不是同步方法,则一个调用线程的阻塞并不会影响到其他调用线程,问题就可以避免了。当然,这里的同步方法本身是合理的,因为只有采取同步的方式才能保证对Cache的读取是支持并发的。达内长沙java培训认为书中给出这个例子,无非是要说明同步方法潜在的危险,提示我们在编写代码时,需要考虑周全。

上一篇:互斥锁之使用类的一个属性

下一篇:达内长沙java培训解析:创造式设计

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:7月31日

Java--零基础业余班

Java--零基础业余班

开班日期:7月31日

Java--大数据全日制班

Java--大数据全日制班

开班日期:7月31日

Java--大数据业余制班

Java--大数据业余制班

开班日期:7月31日

  • 网址:http://cs.java.tedu.cn     地址:长沙市开福区芙蓉中路一段 476 号建鸿达现代城 9 楼
  • 课程培训电话:18487146383     全国服务监督电话:400-111-8989
  • 服务邮箱 tousu@tedu.cn
  • 2001-2016 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56