Java Vector<E> 在没有明显原因的情况下被阻止

标签 java blocking jxta

我可能做错了什么,但这就是发生的事情:

我注册了一个监听器,等待它被调用,当它执行并调用“Vector.clear()”时,它会锁定。问题发生在“pipeMsgEvent”方法中,这里是看起来不太友好的代码(如果您愿意,可以直接转到“这很重要”行):

public class JxtaCustomer implements PipeMsgListener {
    public static final int ANSWER_OK        = 0;
    public static final int ANSWER_TIMEOUT   =-1;
    public static final int ANSWER_NOT_ASKED =-2;
    public static final int ANSWER_WORKING   =-3;

    public static final int REQ_SENT         = 0;
    public static final int REQ_INV_PIPE_ID  =-1;
    public static final int REQ_INV_PIPE_IO  =-2;
    public static final int REQ_INV_GROUP_ID =-3;

    protected int answer;

    protected JxtaGenericAdvertisement serviceAdv = null;
    protected JxtaNode ThePeer = null;

    JxtaBiDiPipe myBiDiPipe = null;
    protected Vector<Entry> output = null;

    public JxtaCustomer(JxtaGenericAdvertisement adv, JxtaNode peer)
    {
        ThePeer = peer;
        serviceAdv = new JxtaGenericAdvertisement((Element)adv.getDocument(new MimeMediaType("text/xml")));

        answer = ANSWER_NOT_ASKED;
        Vector<Entry> output = new Vector<Entry>();
    }

    public void pipeMsgEvent(PipeMsgEvent event)
    {
        System.out.println("It Works! Uhuuu");
        // We received a message
        Message message = event.getMessage();

        System.out.println("Lets GO! Uhuuu");
        Message.ElementIterator elIt = message.getMessageElementsOfNamespace( serviceAdv.getName() );

        System.out.println("A little bit more");
        answer = ANSWER_WORKING;

        System.out.println("enter");

        // This is important: Here I get stuck, "clear"
        // never appears on the screen
        output.clear();
        System.out.println("clear");
        while (elIt.hasNext()) {
            MessageElement mElem = elIt.next();
            System.out.println(mElem.getElementName() + " " + mElem.toString());
            output.add( new Entry( mElem.getElementName(), mElem.toString() ) );
        }
        System.out.println("leave");

        answer = ANSWER_OK;
    }

    public int sendRequest(Vector<Entry> params)
    {
        try {

            // Creating Pipe Advertisement
            String pipeAdvType = PipeAdvertisement.getAdvertisementType();
            PipeAdvertisement pipeAd = (PipeAdvertisement)AdvertisementFactory.newAdvertisement(pipeAdvType);

            URI pipeURI = new URI(serviceAdv.getPipeID());
            pipeAd.setPipeID( IDFactory.fromURI(pipeURI) );
            pipeAd.setType(PipeService.UnicastType);
            pipeAd.setName(serviceAdv.getName() + " Service Pipe");
            pipeAd.setDescription("Created by " + serviceAdv.getName());

            // Creating Group
            JxtaGroup jxgp = ThePeer.getGroupFromID( serviceAdv.getGroupID() );
            if (null == jxgp)
                return REQ_INV_GROUP_ID;

            PeerGroup group = jxgp.getPeerGroup();
            if (null == group)
                return REQ_INV_GROUP_ID;

            // This is important: In the JxtaBiDiPipe call I register
            // the callback, while I have access to the code, I think
            // the problem is in my code
            myBiDiPipe = new JxtaBiDiPipe( group, pipeAd, 30000, this);

            if (myBiDiPipe.isBound()) {
                Thread.sleep(500);

                Message myMessage = new Message();

                if (0 == params.size())
                    params.add( new Entry("dummy", "null") );

                for (int i=0; i<params.size(); i++) {
                    String Key = params.get(i).getKey();
                    String Value = params.get(i).getValue();
                    StringMessageElement strMsgElem = new StringMessageElement( Key, Value, null);
                    myMessage.addMessageElement( serviceAdv.getName(), strMsgElem);
                }

                myBiDiPipe.sendMessage(myMessage);

                answer = ANSWER_TIMEOUT;

                return REQ_SENT;
            }
        } catch (URISyntaxException e){
            e.printStackTrace();

            return REQ_INV_PIPE_ID;
        } catch (IOException e) {
            return REQ_INV_PIPE_IO;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return REQ_INV_PIPE_IO;
    }

    public Vector<Entry> getResponse()
    {
        Vector<Entry> results = new Vector<Entry>();

        if (ANSWER_OK != answer)
            return results;

        // This is important: I always call "getState()" and check its value
        // before calling this method, so you can say it's guaranteed to be
        // called after answer = ANSWER_OK, which never happens because of the
        // lock
        for (int i=0; i<output.size(); i++)
            results.add( output.get(i) );

        return results;
    }

    public int getState()
    {
        int count = 10;

        return answer;
    }
}

我总是像这样创建 JxtaCustomer:

JxtaCustomer customer = new JxtaCustomer(adv, ThePeer);
Vector<Entry> params = new Vector<Entry>();

params.add( new Entry("key1", "value1") );
params.add( new Entry("key2", "value2") );

customer.sendRequest(params);

while(JxtaCustomer.ANSWER_OK != customer.getState()) {
   // I was actually using synchronized locks and timed waits
   // but since I'm stuck there I'm using this nonsense instead
}

Vector<Entry> response = customer.getResponse();

这里是我在代码中调用“ sleep ”、“等待”或创建“同步”的位置(最后一个永远不会)

$ grep synchronized $(find . -name "*.java")

$ grep sleep $(find . -name "*.java")
./Src/net/ubi/jxta/JxtaCustomer.java:                Thread.sleep(500);

$ grep wait $(find . -name "*.java")
./App/ExampleServices/SimpleSigner.java:    boolean waiting = false;
./App/ExampleServices/SimpleSigner.java:        waiting = true;
./App/ExampleServices/SimpleSigner.java:        return (waiting && JxtaCustomer.ANSWER_OK == customer.getState());
./App/ExampleServices/SimpleSigner.java:        if (!waiting)
./App/ExampleServices/SimpleSigner.java:            waiting = false;
./App/ExampleServices/SimpleSigner.java:            return "Error: Response not ready, wait more time\n";

最佳答案

你的构造函数设置了一个名为output的局部变量,而不是你的成员变量

Vector<Entry> output = new Vector<Entry>();

什么时候应该

output = new Vector<Entry>();

因此,稍后当您调用 output.clear() 时,您会抛出空指针异常,这就是为什么以下代码行不会被执行。

诸如“未使用的局部变量”之类的编译器警告可以帮助发现此类错误。

关于Java Vector<E> 在没有明显原因的情况下被阻止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4445256/

相关文章:

java - 为不同的语言环境定制 java.text 格式化程序

Python recv 多播返回一个字节

java - 如何强制 socket.close 释放写 block

Android P2P 多人游戏 (a) XMPP/Google talk b) JXTA peerdroid c) 其他方式)

java - 是否有用于 Java P2P 框架的 JXTA 的替代品?

java - 在 Java 中创建新对象并将其传递给 setMethod 的问题

java - 在 Java 中获取客户端的每个 IP 地址的问题

java - 通过引用其他测试套件从测试套件执行 Junit4 测试

c++ - 可以使用 `waitForReadyRead()` 而不是为 `readyRead()` 信号创建插槽吗?

java - JXTA中哪里可以找到NetworkManager.RecursiveDelete();