Java Can";CopyOnWriteArrayList“;及;ConcurrentHashMap“;要连载吗?

Java Can";CopyOnWriteArrayList“;及;ConcurrentHashMap“;要连载吗?,java,serialization,thread-safety,rmi,concurrenthashmap,Java,Serialization,Thread Safety,Rmi,Concurrenthashmap,我有一个使用RMI的类传送。但我不确定这些线程安全对象是否可以序列化。以前有人尝试过吗 更新 斯卡夫曼说可以,但我连载失败了 这是我传送的类 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package net.shisoft.beans; import java.util.concurrent.ConcurrentHashMap; impo

我有一个使用RMI的类传送。但我不确定这些线程安全对象是否可以序列化。以前有人尝试过吗

更新 斯卡夫曼说可以,但我连载失败了

这是我传送的类

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.shisoft.beans;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 *
 * @author Shisoft
 */
public class WhatzNewList {

    ConcurrentHashMap<String, CopyOnWriteArrayList<WhatzNewEntry>> WhatzNewTable = new ConcurrentHashMap<String, CopyOnWriteArrayList<WhatzNewEntry>>();
    String user;

    public ConcurrentHashMap<String, CopyOnWriteArrayList<WhatzNewEntry>> getWhatzNewTable() {
        return WhatzNewTable;
    }

    public void setWhatzNewTable(ConcurrentHashMap<String, CopyOnWriteArrayList<WhatzNewEntry>> WhatzNewTable) {
        this.WhatzNewTable = WhatzNewTable;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String usere) {
        this.user = usere;
    }

    public WhatzNewList(String user) {
        this.user = user;
    }
}

可能skaffman是对的,但这里有什么错?

它们都实现了
java.io.Serializable
。所以是的,它们可以被序列化

当然,它们的内容是否可以序列化是一个完全不同的问题。

ConcurrentHashMaps(CHM)是无法高效序列化的重量级对象。为什么要序列化所有锁定信息

转换为HashMap、Map、Set甚至toString()这样的中间对象效率更高

当然,最有效的方法是根本不使用默认的可序列化行为,而是编写自己的可外部化接口,该接口使您能够完全控制缓冲区内容

下面是一个序列化的空CHM:

​sr&java.util.concurrent.ConcurrentHashMapd™Þ‡)=I segmentMaskI segmentShift[segmentst 1[Ljava/util/concurrent/ConcurrentHashMap$Segment;xp ur 1[Ljava.util.ConcurrentHashMap$Segment;Rw?A2›9t xp sr.java.util.ConcurrentHashMap$Segment6LX”)=F loadFactorxr(java.util.concurrent.locks.ReentrantLockfU¨,ÈjëL synct/Ljava/util/concurrent/locks/ReentrantLock$Sync;xpsr 4java.util.concurrent.locks.ReentrantLock$NonfairSynceˆxr-java.util.concurrent.locks.ReentrantLock$Sync)ªDZ|xr 5java.util.concurrent.locks.AbstractQueuedSynchronizerfU¨Cu?RãI statexr 6java.util.concurrent.locks.AbstractOwnableSynchronizer3ßñmo©xp?@sq~sq~?@sq~sq~?@sq~sq~?sq~sq~?@sq~sq~?@sq~sq~?@sq~sq~~sq~?@sq~sq~?@sq~sq~?@sq~sq~?@sq~sq~?@sq~sq~?@ppx

Gross。这是从toString()序列化的同一个CHM:

èt{}


通过做一点转换工作,您可以节省大量带宽!

有趣的是,如果我在我的UnitTest测试类中使用序列化,并且我尝试序列化类(完全可序列化),但以这种方式包含CopyOnWriteArrayList:

public class SerializeTest {
@Test
public void Test() {
// serializeanyserializable class
}
引发异常:

java.io.NotSerializableException:序列化测试 ... 位于java.util.concurrent.CopyOnWriteArrayList.writeObject(CopyOnWriteArrayList.java:857)

调试时,我看到: CopyOnWriteArrayList使用从SerializeTest派生的临时对象,如SerializeTest$1

所以,唯一的解决办法是我必须使测试可序列化,然后它突然开始工作


有人有解释吗?

内容很好:)@extraneon:愚弄我一次,等等,抱歉java.io.NotSerializableException:net.shisoft.beans。WhatzNewList@Shisoft:这是因为您的
WhatzNewList
类是不可序列化的,与原始问题无关。
WhatzNewList
必须实现
java.io.serializable
@Shisoft:我查看了源代码对于CopyOnWriteArrayList及其writeObject。有可能一个线程正在序列化它,而另一个线程正在修改它。在这种情况下,序列化版本将过时。我想我应该提到它。您需要将
implements Serializable
添加到
WhatzNew*
类定义中。
public class SerializeTest {
@Test
public void Test() {
// serializeanyserializable class
}