0

1 つのスレッドで XML ファイルを読み取り、2 つのスレッドを介していくつかのノードを追加したいと考えています。ライター スレッドは同時にファイルに書き込むことはできません。また、リーダー スレッドはファイルの内容を読み取ってバッファーに入れます。リーダーがこの操作を行うと、ライターはこのバッファーにアクセスできません。

これどうやってするの??

私はXMLファイルを読み、この方法でこれにノードを追加します:

public synchronized void AddNewNode(Document doc) throws TransformerException {

    Element book = doc.createElement("book");
    book.setAttribute("id", "3");

    Element name = doc.createElement("name");
    name.setTextContent("new");
    Element id = doc.createElement("id");
    id.setTextContent("31");
    Element writer = doc.createElement("writer");
    writer.setTextContent("tester");
    Element price = doc.createElement("price");
    price.setTextContent("3100");

    book.appendChild(name);
    book.appendChild(id);
    book.appendChild(writer);
    book.appendChild(price);

    doc.getDocumentElement().appendChild(book);

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    DOMSource source = new DOMSource(doc);
    StreamResult result = new StreamResult("/home/zahra/workspace/test1/src/xmlfile.xml");
    transformer.transform(source, result);

}
public void ReadNodes(Document doc) {

    NodeList nList = doc.getElementsByTagName("book");
    System.out.println("\n" + ":0 :) :0 :) :0 :) :0 :) :0 :)");
    for (int i = 0; i < nList.getLength(); i++) {

        Node nNode = nList.item(i);
        System.out.println("\n" + "Element number " + (i + 1) + "\n");
        Element eElement = (Element) nNode;
        for (int j = 0; j < eElement.getChildNodes().getLength(); j++) {

            String tagName = eElement.getChildNodes().item(j).getNodeName();
            if (eElement.getElementsByTagName(tagName).getLength() > 0) {
                System.out.println(eElement.getChildNodes().item(j).getNodeName()
                        + " : "
                        + eElement.getElementsByTagName(tagName).item(0).getTextContent());
            }
        }

    }

}

ありがとう!

4

1 に答える 1

1

synchronizedメソッド修飾子として使用する方法には十分注意してください。多くの場合、期待どおりに動作しません。synchronizedメソッド修飾子は、次の構文糖衣と考えるのが好きです。

public void myMethod() {
    synchronized(this) {
        // method body
    }
}

インスタンス自体をロックするため、同じインスタンスが同時にメソッドを呼び出すことのみを制限します。たとえば、ライターごとに 1 つのインスタンスを作成した場合、同期メソッドはまったく役に立ちません。あなたの場合、よりクリーンになるのは、次のように、ロックしたいオブジェクトを直接同期することです。

public void addNewNode(Document doc) throws TransformerException {

    synchronized(doc) {
        Element book = doc.createElement("book");
        book.setAttribute("id", "3");
        // etc, etc.
    }
}

Reader メソッドで同じトリックを実行できる可能性がありますが、その場合、リーダーは両方のライターもブロックします。ただし、そのようなスレッド化とタイミングが必要なユースケースについては正確にはわかりません。マルチスレッドが完全に機能するようになったとしても、読み取りが実際にすべての書き込みをカバーしているかどうかという問題が残ります (最後の読み取りの直前に書き込みが発生する競合ケースが発生する可能性があります)。

于 2013-03-14T09:23:53.850 に答える