这个类从InputStream类中派生,构造函数很特别,为一个protected类型 protected FilterInputStream(InputStream in) {    this.in = in;    };protected volatile InputStream in; in也为保护类型,显示是为了子类的使用,而不是直接是用这个类。这个类可以算是InputStream类的一种,用来标志那些从不同起源地产生的输入类,这些起源地包括字节数组、string对象、文件、管道、internet等。通过FilterInputStream将不同发源地的输入类转化为InputStream对象。此正为Filter的含义所在。

其中in定义为volatile类型,volatile修饰符主要作用为:当多个线程要访问volatile修饰的变量时,强迫从共享内存中重读该变量的值,而且当成员变量的值发生变化时,强迫线程将值写入到共享内存中;这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低因此一定在必要时才使用此关键字。因此可以说volatile的同步是在变量级别的,它的代价比同步synchronized要低。但是volatile不能保证数据的原子性,会出现脏数据。

• public class TestRaceCondition {   
• private volatile int i = 0;   
• 
• public void increase() {   
•        i++;   
•     }   
• 
• public int getValue() {   
• return i;   
•     }
  • }  当取出i的值进行加1操作时,其他线程可能已经对i修改了无数次,而最终i++的操作会抹掉以前的修改,因此会出现脏数据。volatile仅仅能保证共享数据的一致性, 无法保证线程间的同步.
    顺便介绍些transient关键字:
    java有个特点就是序列化,简单地来说就是可以将这个类存储在物理空间(当然还是以文件的形式存在),那么当你从本地还原这个文件时,你可以将它转换为它本身。这可以极大地方便网络上的一些操作,但同时,因为涉及到安全问题,所以并不希望把类里面所有的东西都能存储(因为那样,别人可以通过序列化知道类里面的内容),那么我们就可以用上transient这个关键字,它的意思是临时的,即不会随类一起序列化到本地,所以当还原后,这个关键字定义的变量也就不再存在。