比如 我有一个线程 用InputStream不停的读消息 另一个线程 用OutputStream写消息  。发现消息无回应 。这个线程 会把 OutputStream。InputStream 关闭 。让程序从新连接。  但是他关闭的时候 ,另外一个线程 的InputStream依然继续执行 。如果不同步的话。可以用volatile 吗。我试了一下好像不行。

解决方案 »

  1.   


    volatile 不能用于同步2个线程对此变量的写操作
    volatile 一般处理是单线程写  多个线程读
    因为volatile是可见性的 不是互斥的如果你要保持数据完整性  我建议你不要用  volatile 修饰 InputStream  你这里的情况有多个地方对InputStream进行 写操作了   包括底层填充数据  这里我不知道说的对不对   等待后面的人回答吧
      
    一般使用volatile 基本都是基本数据类型才用这个  boolean int 等    但是排除特殊情况网络上去查下volatile的基本用法 你就知道了 
      

  2.   

    volatile  是实现可见 不提供互斥这个我知道。  我这里也排除了 同时读写一个InputStream。。我只是说 一个线程 一直 用InputStream读 ,另外一个线程 突然把InputStream。close掉 。如果把InputStream设置为 volatile  。那么应该是可见的 。这个线程应该 知道InputStream被close了 。这样 如果在read就应该报异常。
    我觉得 volatile  应该是这样 的 吧 ,但是事实好像不是如此 。所以我想知道,是不是只有 基本数据类型可以用  volatile  。
      

  3.   

         简单来说 volatile 这个关键字 在修饰 初基本类型之外 可以修饰其他的类型吗 。
    比如我这里的 InputStream。。    加入有2个线程 ,(都可以看到InputStream )一个线程a用InputStream 不停的读数据。  另外一个线程b 突然把这个InputStream。close了。。   因为InputStream 不是同步的 。b对inputstream的操作 a应该看不到 。所以a依然可以用InputStream 不停的读数据。
    这个时候如果 把volatile  修饰 InputStream  。那么按照volatile  的用法 ,a线程就应该可以看到 
    InputStream 的改变 。   我问是不是这样的 ,可以用吗?
      

  4.   

    两个线程对同一个流操作,一个线程关闭该流,另外个线程不能再读流了,因为没有数据了,除非没有关闭,
    建议使用同步语句  synchronized
    如:
    synchronized(流对象){
    流对象.read();
    }
      

  5.   

    你的流对象会不停变更么?如果不会就不要用 volatile,楼主这样的想法很奇怪,仔细考虑一下你的需求吧
      

  6.   

    我不是研究这个项目 ,我的意思 是 按照我以上说的情况 volatile 修饰 InputStream  。如果 inputstream 被另外一个线程b关闭了。 那么 这个线程a是不是应该可以看得到 。就应该报异常了吧。。但是事实上我测试的结果 是,  这个线程依然在读数据。 并没有收到另外一个线程 关闭这个inputstream的影响。。这是不是说 volatile 在这里没用处 。他只能修饰 基本类型的。
      

  7.   

    你确定关闭这个流了吗?调试一下,
    对对象同步操作用最好用synchronized语句,
    对基本类型才用volatile 
      

  8.   

    iaps = new IapsObj(this, iapsHost, port); //这个对象 里面有个 InputStream 
          他本身继承是个runable把他放入线程 t执行。
    Thread t = new Thread(iaps, this + "-[iaps-" + iapsHost);
    t.start();然后另外一个线程  把 iaps类作为参数传入                   hbThread = new IapsHBThread(iaps);
    Thread t2 = new Thread(hbThread, this + "-[hbThread]");
    t2.start();
    然后在 t2里面调用 iaps类的 方法。
    private void invalidSocket() {
    try {
    this.streamToServer.close();
    this.streamFromServer.close();
    this.connectedSocket.close();
    streamToServer = null;
    streamFromServer = null;
    connectedSocket = null;
    } catch (Exception e) {
    } }但是线程t 此时 streamToServer依然可以read 。。但是如果t线程 自己从新连接 ,赋值输入流 。t2线程确可以看到。
    不管加不加 volatile 修饰,都是一样。