A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 董将 中级黑马   /  2012-12-7 23:43  /  973 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

售票的例子。

        --------------------------------------
       
        多线程的安全问题:
        售票时居然会发生打印负号票的情况。

        造成安全问题的原因:
        多条语句在对同一数据资源进行操作,而这些语句被多个线程分开执行时,容易出现数据资源错误。
        而到值安全问题的产生。

        解决思想:
        那就是将这多条语句进行封装,一次只能让一个线程都执行完后,才让另一个线程执行该代码。

        解决方式:
        同步 。

        同步的原理:就是将代码进行封装,并加锁。

        同步的前提:
                1,要有两个或者两个异常的线程。
                2,必须多个线程使用的是同一个锁。

        同步的格式:
                1,同步代码块。
                        synchronized(obj)
                        {
                                需要被同步的语句。
                        }
                2,同步函数。
                        其实就是在函数上加上一个synchronized修饰符。

        两个格式有什么区别?
        同步代码块可以让任意对象作为锁存在。只要保证多个线程用的是同一个对象(锁)即可。
        同步函数使用的锁是this。

        注意:当同步函数被static修饰时,那么这时使用的锁就不是this了。因为静态函数不具备this引用。
                使用的锁是 该类对应的字节码文件对象。该对象的表现形式是: 类名.class

        不得不提:单例设计模式的懒汉式。
        class Single
        {
                private static Single s = null;

                private Single(){}

                public static Single getInstance()
                {
                        if(s==null)
                                s = new Single();
                        return s;
                }
        }
        当多线程并发访问getInstance()方法时,容易出现线程安全问题。不能保证对象的唯一性。

        这时我们需要将其同步。那么将该函数用synchronized 关键字修饰是可以解决安全问题的。
        但是效率很低。
        这时可以采取一种优化的方式。双重判断的形式。

        public static Single getInstance()
        {
                if(s==null)
                {
                        synchronized(Single.class)
                        {
                                if(s==null)
                                        s = new Single();
                        }
                }
                return s;
        }


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马