【问题标题】:Can "CopyOnWriteArrayList" and "ConcurrentHashMap" be serialized?“CopyOnWriteArrayList”和“ConcurrentHashMap”可以序列化吗?
【发布时间】:2011-06-19 12:24:11
【问题描述】:

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

更新 skaffman 说可以,但是我序列化失败了。

这是我传送的课程。

/*
 * 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;
    }
}

这是课程WhatzNewEntry

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

import java.util.Date;

/**
 *
 * @author Shisoft
 */
public class WhatzNewEntry {
    String Title;
    String context;
    String contact;
    Date Time;

    public Date getTime() {
        return Time;
    }

    public void setTime(Date Time) {
        this.Time = Time;
    }

    public String getTitle() {
        return Title;
    }

    public void setTitle(String Title) {
        this.Title = Title;
    }

    public String getContact() {
        return contact;
    }

    public void setContact(String contact) {
        this.contact = contact;
    }

    public String getContext() {
        return context;
    }

    public void setContext(String context) {
        this.context = context;
    }

}

也许斯卡夫曼是对的,但这里有什么问题?

【问题讨论】:

  • 您需要将implements Serializable 添加到您的WhatzNew* 类定义中。

标签: java serialization thread-safety rmi concurrenthashmap


【解决方案1】:

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

他们的内容是否可以序列化,当然,完全是另外一个问题。

【讨论】:

  • contents 不错 :)
  • @extraneon:骗我一次,等等
  • 呃,对不起 java.io.NotSerializableException: net.shisoft.beans.WhatzNewList
  • @Shisoft:那是因为您的 WhatzNewList 类不可序列化,与您的原始问题无关。 WhatzNewList 必须实现 java.io.Serializable
  • @Shisoft:我查看了 CopyOnWriteArrayList 及其 writeObject 的源代码。有可能当一个线程正在序列化它时,其他一些线程正在修改它。在这种情况下,序列化版本将是陈旧的。觉得我应该提一下。
【解决方案2】:

ConcurrentHashMaps (CHM) 是重量级的对象,没有被有效地序列化。例如。为什么要序列化所有锁定信息?

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

最有效的当然是根本不使用默认的 Serializable 行为,而是编写自己的 Externalizable 接口,让您完全控制缓冲区内容。

例如。 - 这是一个序列化的空 CHM:

¬í sr &java.util.concurrent.ConcurrentHashMapd™Þ‡)= I segmentMaskI segmentShift[ segmentt 1[Ljava/util/concurrent/ConcurrentHashMap$Segment;xp ur 1[Ljava.util.concurrent.ConcurrentHashMap$Segment;Rw ?A2›9t xp sr .java.util.concurrent.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^2çS{¿ 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 ~ sq ~ ?@ sq ~ sq ~ ?@ sq ~ sq ~ ?@ ppx

毛。这是从 toString() 序列化的相同 CHM:

’ t {}

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

【讨论】:

    【解决方案3】:

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

    public class SerializeTest {
    @Test
    public void Test() {
    // serializeanyserializable class
    }
    

    抛出异常:

    java.io.NotSerializableException: SerializeTest ... 在 java.util.concurrent.CopyOnWriteArrayList.writeObject(CopyOnWriteArrayList.java:857)

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

    所以,唯一的解决方案是我必须使 Test 可序列化,然后它突然开始工作。

    有人解释吗?

    【讨论】:

      猜你喜欢
      • 2013-04-03
      • 1970-01-01
      • 1970-01-01
      • 2013-02-22
      • 1970-01-01
      • 2012-07-20
      • 2018-06-21
      • 2014-10-19
      • 2013-07-21
      相关资源
      最近更新 更多