`
xieyj
  • 浏览: 100293 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

synchronized错误用法

阅读更多

    翻起tomcat5的源码,看到standardServer.java中的addservice方法:

 

    public void addService(Service service) {

 

        service.setServer(this);

 

        synchronized (services) {

            Service results[] = new Service[services.length + 1];

            System.arraycopy(services, 0, results, 0, services.length);

            results[services.length] = service;

            services = results; ---此处会导致同步失效,因为改写了锁的对象,也就是锁指向的区域发生了改变

 

            if (initialized) {

                try {

                    service.initialize();

                } catch (LifecycleException e) {

                    e.printStackTrace(System.err);

                }

            }

 

            if (started && (service instanceof Lifecycle)) {

                try {

                    ((Lifecycle) service).start();

                } catch (LifecycleException e) {

                    ;

                }

            }

 

            // Report this property change to interested listeners

            support.firePropertyChange("service", null, service);

        }

 

    }

    由于Thread.Sleep()不会失去拥有的对象锁,做个例子验证一下

        public class Test {

 

        private static Object lock = new Object();

        public static void main(String[] args) {

 

        new Thread(){

                public void run() {

                       synchronized (lock) {

                             System.out.println("thread1-----enter");

                             lock = new Object() ; //更换锁的对象

                             try {

                                   Thread.sleep(3000); //让线程2可以运行,看是否能进入代码块

                             } catch (InterruptedException e) {

                                    e.printStackTrace();

                             }

                             System.out.println("thread1-----exit");

                      }

               }

        }.start();

        new Thread(){

                public void run() {

                      try {

                            Thread.sleep(1000);//让上面的线程1先进入同步代码块

                      } catch (InterruptedException e) {

                            e.printStackTrace();

                      } 

                      synchronized (lock) {

                              System.out.println("thread2-----enter");

                              System.out.println("thread2-----exit");

                      }

             }

       }.start();

    }

}

输出的结果为

thread1-----enter

thread2-----enter

thread2-----exit

thread1-----exit

可见上面的同步失败,连写tomcat的大牛都出错,synchronized的坑真不小。

分享到:
评论

相关推荐

    Java中synchronized正确使用方法解析

    主要介绍了Java中syncronized正确使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java学习题答案

    不能使用IO操作直接存取文件系统 6.不能加载本地库. 7.不能将this作为变量和返回. 8.不能循环调用. public String toString(){ return this + "@" + this.hashCode(); } 会变成 public ...

    超级有影响力霸气的Java面试题大全文档

    此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),...

    最全java考试简答题

    1. 解释下列关键字的含义,并说明其在编程中的作用: protected,final,throw,super,synchronized,static,finally,abstract,...使用 `throw` 抛出异常,让程序转入异常处理程序来处理这个错误,从而保证程序的正

    华为java经典面试题大总结

    此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),...

    Lock锁的底层原理完整版

    Lock锁,一种线程同步机制,其主要功能是防止多个线程同时访问同一代码块,从而避免因并发问题引发的数据不一致或其他错误。Lock锁的灵活性相比synchronized更高,它支持手动获取和释放锁,能够中断的获取锁以及超时...

    Java面向对象程序设计试题一.doc

    C2、paint ( )方法使用哪种类型的参数? A Graphics B Graphics2D C String D Color D3、指出正确的表达式 ( ) A byte=128; B Boolean=null; C long l=0xfffL; D double=0.9239d; 4、指出下列程序运行的结果 ( )...

    java 面试题 总结

    此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),...

    JAVA面试题最全集

    被声明为final的方法也同样只能使用,不能重载 finally?再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。 ...

    最全面试笔试整合(比较齐全包括网页,文档。。。)

    此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),...

    java面试题

    当一个线程进入一个对象的synchronized方法后,其他线程是否可进入此对象的其他方法? 答:其他方法前是否加了synchronized关键字,如果没加则能。 说出servlet生命周期? 答:servlet实例化时调用init方法,得到...

    二十三种设计模式【PDF版】

    设计模式之 Template(模板方法) 实际上向你介绍了为什么要使用 Java 抽象类,该模式原理简单,使用很普遍. 设计模式之 Strategy(策略) 不同算法各自封装,用户端可随意挑选需要的算法. 设计模式之 Chain of ...

    千方百计笔试题大全

    72、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 18 73、线程的基本概念、线程的基本状态以及状态之间的关系 18 74、sleep() 和 wait() 有什么区别? 18 75、socket...

    java基础案例与开发详解案例源码全

    12.5.1 使用synchronized同步块324 12.5.2 使用集合工具类同步化集合类对象324 12.5.3 使用JDK5.0后提供的并发集合类324 12.6 用Timer类调度任务325 12.7 本章练习326 第13章 13.1 java.io.File类328 13.1.1 文件和...

    java面试宝典

    72、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 18 73、线程的基本概念、线程的基本状态以及状态之间的关系 18 74、sleep() 和 wait() 有什么区别? 18 75、socket通信...

    数据连接池

    * 将不再使用的连接返回给连接池 * * @param con 客户程序释放的连接 */ public synchronized void freeConnection(Connection con) { // 将指定连接加入到向量末尾 freeConnections.addElement(con); ...

    java多线程中测试同步的小程序

    目的是为了测试多线程编程下如何使用同步(synchronized)防止产生竞争共享资源的错误状态,从中得到的心得是:一定要将你所共享的变量封装在一个类中,将所有有关该变量的操作方法都尽可能地封装在包含该变量的类中...

    java设计模式CatalogDAOFactory是典型的工厂方法

    使用工厂方法 要注意几个角色,首先你要定义产品接口,如上面的Sample,产品接口下有Sample接口的实现类,如SampleA,其次要有一个factory类,用来生成产品Sample,如下图,最右边是生产的对象Sample: 进一步稍微...

Global site tag (gtag.js) - Google Analytics