zoukankan      html  css  js  c++  java
  • 对象的组合

    1. 设计线程安全的类

    在设计线程安全类的过程中,需要包含以下三个基本要素:

    • ·找出构成对象状态的所有变量
    • 找出约束变量的不变性条件
    • 建立对象状态的并发访问管理策略

    示例1:  使用Java监视器模式的线程安全计数器

    @ThreadSafe
    public class Counter {
    
        @GuardedBy("this") private long value=0;
        public synchronized long getValue() {
            return value;
        }
        
        public synchronized long increment() {
            if(value==Long.MAX_VALUE)
                throw new IllegalStateException("Counter overflow");
            return ++value;
        }
    }

    2. 实例封闭

      一种避免使用同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要同步。这种技术称为线程封闭,它是实现线程安全的最简单方式之一。  

      将数据封装在对象内部,可以将数据的访问限制在对象的方法上,从而更容易确保线程在访问数据时总能持有正确的锁。

    被封闭对象一定不能超出它们既定的作用域。对象可以封闭在类的一个实例(例如作为类的一个私有成员)中,或者封闭在某个作用域内(例如作为一个局部变量),再或者封闭在线程内(例如在某个线程中将对象从一个方法传递到另一个方法,而不是在多个线程之间共享该对象)。

    示例二: 通过封闭机制来确保线程安全*(注:Person是线程安全类)

    @ThreadSafe
    public class PersonSet {
        @GuardedBy("this")
        private final Set<Person> mySet=new HashSet<Person>();
        
        public synchronized void addPerson(Person p) {
            mySet.add(p);
        }
        
        public synchronized boolean containPerson(Person p) {
            return mySet.contains(p);
        }
    }

       PersonSet说明了如何通过封闭加锁等机制使一类成为线程安全的(即使这个类的状态变量并不是线程安全的)。PersonSet的状态由HashSet来管理,而HashSet并不是线程安全的,但由于mySet是私有的并且不会溢出,因此HashSet被封闭在PersonSet中。唯一能访问mySet的代码路径为addPerson和containPerson,在执行它们时必须要获得PersonSet上的锁。PersonSet的状态完全由它的内置锁保护,因而PersonSet是一个线程安全的类。

     总结:封闭机制更易于构造线程安全的类,因为当封闭类的状态时,在分析类的线程安全性时就无须检查整个程序。

    2.1 Java监视器模式

      遵循Java监视器模式的对象会把对象的所有可变状态都封装起来,并由对象自己的内置锁来保护。在许多类中都使用了该模式,例如Vector和Hashtable。

      Java监视器模式仅仅是一种编写代码的约定,对于任何一种对象,只要自始至终都使用该锁对象,都可以用来保护对象的状态。

                        通过一个私有锁来保护状态  

    public class PrivateLock {
        private final Object myLock=new Object();
        
        @GuardedBy("mybLock")Widget widget;
        
        void someMethod() {
            synchronized (myLock) {
                //访问或修改wiget的状态
            }
        }
    
    }

      使用私有锁而不是对象的内置锁(或任何其他可通过公有方式访问的锁), 有许多优点。私有的锁对象可以将锁封装起来,是客户代码无法得到锁,但客户代码可以通过公有方法来获得锁。这是书上的原话,然而看不懂....。首先要搞明白的是私有锁和内置锁的区别,在网上看到一篇不错的博文:http://www.jb51.net/article/56440.htm

      1. 类锁:在代码中的方法上加了static和synchronized的锁,或者synchronized(xxx.class)的代码段。

      2.对象锁:在代码中的方法上加了synchronized的锁,或者synchronized(this)的代码段。

      3.私有锁:在类内部声明一个私有属性如private Object lock,在需要加锁的代码段synchronized(lock)。

      4.内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。

      看来内置锁和对象锁是一回事了,只不过角度不同定义自然不一样。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • 相关阅读:
    【转载】COM 组件设计与应用(十一)—— IDispatch 及双接口的调用
    【转载】COM 组件设计与应用(十)——IDispatch 接口 for VC.NET
    网易云课堂_Linux操作系统入门(嵌入式开发零基础Ⅰ)_章节3:Linux 命令(下)
    网易云课堂_Linux操作系统入门(嵌入式开发零基础Ⅰ)_章节2:Linux 命令(上)
    网易云课堂_艾叔:零基础一站式C语言|C程序设计精讲_章节12:指针
    网易云课堂_艾叔:零基础一站式C语言|C程序设计精讲_章节8:输入与输出
    网易云课堂_艾叔:零基础一站式C语言|C程序设计精讲_章节5整型
    Vim应用
    gcc编译命令
    虚拟机使用PuTTY、SSH Secure Shell Client前的配置
  • 原文地址:https://www.cnblogs.com/ktao/p/8410476.html
Copyright © 2011-2022 走看看