浏览 2911 次
锁定老帖子 主题:关于Socket的一个异常
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-04-07
最后修改:2010-04-07
此异常的出现,是在java.net.SocketInputStream中抛出来的,首先来看一下源码: class SocketInputStream extends FileInputStream { static { init(); } private boolean eof; private PlainSocketImpl impl = null; private byte temp[]; private Socket socket = null; /********* 部分省略 ************/ if (impl.isConnectionReset()) { /*异常由此处抛出*/ throw new SocketException("Connection reset"); } 由此可见,是因为调用方法的时候触发了 PlainSocketImpl中的 isConnectionReset()方法,继续寻根问底,看看到底isConnectionReset()做了 什么操作,继续看代码: class PlainSocketImpl extends SocketImpl { /* ** ** 部分代码省略 *****/ private int resetState; private int CONNECTION_RESET = 2; private Object resetLock = new Object(); public boolean isConnectionReset() { synchronized (resetLock) { return (resetState == CONNECTION_RESET); } } /* ** ** 部分代码省略 *****/ } 仔细看,在isConnectionReset方法中 对创建的对象流进行了加锁?然后注释都没有写这个地方用来干嘛的????? 而且大家仔细看下,这个类名不是public的,在类的注释中有这样一句话: This implementation does not implement any security checks. 对这些很是不解,其中有一句这样的代码: private Object resetLock = new Object();这些东西看起来只是对他进行了安全控制,用的同步的方法,为什么这么弄?原本是想把问题好好搞明白,结果越看越深,更迷糊了,后面又继续查看源代码就有 java.net.SocketImpl * @see java.net.SocketImplFactory#createSocketImpl() * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @see SecurityManager#checkListen 这些了,看来还得找多点时间好好研究一下才会使问题得到解决,并对此有更深的体会。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-04-11
这个叫虚拟锁。
通常我们对一个类A中的两个方法进行同步操作是在方法上加锁: public synchronized boolean methodA() { /*省略*/ } public synchronized boolean methodB() { /*省略*/ } 在这种情况下,多个线程分别同时调用A实例的methodA(),methodB()方法时,只有一个线程可以获得同步锁,执行一个方法,其他线程需要等待这个线程释放锁了再竞争同步锁,执行他们要执行的方法。 这通常是在methodA和methodB方法中存在对相同共享数据的情况下,为了避免数据的争用而采用的同步操作。如果说这两个方法之间不存在资源争用,但又都需要同步的时候,如PlainSocketImpl类中的releaseFD()和isConnectionReset()这两个方法,你仔细看一下PlainSocketImpl的代码: class PlainSocketImpl extends SocketImpl { /*省略*/ private Object fdLock = new Object(); /*省略*/ private Object resetLock = new Object(); /*省略*/ public final void releaseFD() { synchronized (fdLock) { fdUseCount--; if (fdUseCount == -1) { if (fd != null) { try { socketClose(); } catch (IOException e) { } finally { fd = null; } } } } } public boolean isConnectionReset() { synchronized (resetLock) { return (resetState == CONNECTION_RESET); } } /*省略*/ } 如果采用前面这种对方法或者对类的同步,那么假设A线程在执行PlainSocketImpl实例的releaseFD()时,B线程需要执行PlainSocketImpl实例的isConnectionReset()方法,就需要等待A线程释放同步锁,这种等待是无意义的。 为了解决这个问题,PlainSocketImpl类采用了后面这种虚拟锁的手段,创建了两个虚拟锁对象fdLock和resetLock并分别同步,这样在两个线程分别调用这两个方法时,他们获得的是不同对象的锁,互相没有任何竞争,就可以同步运行,只有两个线程同时调用releaseFD()或isConnectionReset()方法时才会争用同一个锁。 |
|
返回顶楼 | |
发表时间:2010-04-11
近来也在做Socket开发。
明天再试试这个东西。 |
|
返回顶楼 | |
发表时间:2010-04-16
FeiXing2008 写道 近来也在做Socket开发。 明天再试试这个东西。 呵呵,谢谢yechw |
|
返回顶楼 | |