在类之外共享静态数据

时间:2009-06-30 15:13:19

标签: java oop static sharing parallel-processing

首先,这是一个激励性的例子:

public class Algorithm
{
    public static void compute(Data data)
    {
        List<Task> tasks = new LinkedList<Task>();
        Client client = new Client();
        int totalTasks = 10;

        for(int i = 0; i < totalTasks; i++)
            tasks.add(new Task(data));

         client.submit(tasks);
    }
}

// AbstractTask implements Serializable
public class Task extends AbstractTask
{
    private final Data data;

    public Task(Data data)
    {
        this.data = data;
    }

    public void run()
    {
        // Do some stuff with the data.
    }
}

所以,我正在做一些并行编程,并且有一个创建大量任务的方法。这些任务共享他们将要操作的数据,但是我在为每个任务提供数据引用时遇到了问题。问题是,当序列化任务时,会为每个任务创建数据副本。现在,在这个任务类中,我可以对数据进行静态引用,这样它只存储一次,但是在任务类的上下文中这样做并没有多大意义。我的想法是将对象作为静态存储在另一个外部类中,并让任务从类中请求对象。这可以在发送任务之前完成,可能在上面发布的示例中的计算方法中完成。你认为这是合适的吗?任何人都可以提供有关建议的任何替代解决方案或提示吗?谢谢!

5 个答案:

答案 0 :(得分:1)

您能解释一下您所处理的序列化情况吗? Task如何报告结果,以及它在哪里 - 他们是否修改了Data?他们产生了一些产出吗?是否所有任务都需要访问所有Data Task的任何是否写入同一ObjectOutputStream

抽象地说,我想我可以看到两类解决方案。

  1. 如果Task并非都需要访问所有Data,我会尽量为每个Task提供所需的数据。
  2. 如果他们都需要全部,那么我不会让Task包含Data本身,而是让它包含可用于获取数据的某种ID。如何在Data可以运行的每个地点转移Task的一个副本,并且{I}} Task访问它,我不确定,不能更好地了解整体情况。但我建议您尝试单独管理Data

答案 1 :(得分:0)

编辑:由于对被问及的内容存在误解,以下答案实际上并不相关。离开这里等待问题作者的更多细节。


这正是发明transient关键字的原因。

  

声明实例字段不是   默认序列化形式的一部分   一个东西。当一个物体是   序列化,只有它的值   非瞬态实例字段是   包含在默认序列中   表示。当一个物体是   反序列化的瞬态场   仅初始化为默认值   值。

public class Task extends AbstractTask {
    private final transient Data data;

    public Task(Data data) {
        this.data = data;
    }

    public void run() {
        // Do some stuff with the data.
    }
}

答案 2 :(得分:0)

我不确定我是否完全理解这个问题,但对我来说听起来好像是为了以后的执行而实际编写了一系列任务。

如果是这种情况,一个重要的问题是所有Task个对象是否都写入同一个ObjectOutputStream。如果是这样,Data将仅在第一次遇到时被序列化。稍后“副本”将仅引用流中的相同对象句柄。

也许人们可以利用这一点来避免对数据的静态引用(这可能会导致OO设计中的许多问题)。

答案 3 :(得分:0)

您是否考虑过制作单身而不是制作静态?

答案 4 :(得分:0)

  

我的想法是将对象存储为   静态在另一个外部类和   让任务从中请求对象   上课。

忘记这个想法。当任务被序列化并通过网络发送时,该对象将不会被发送;静态数据不能(也不能)在JVM之间以任何方式共享。

基本上,如果您的任务是单独序列化的,那么共享数据的唯一方法是单独发送数据,或者仅在一个任务中发送它,并以某种方式让其他任务在接收机器上获取它。这可能通过静态字段发生,即具有数据集和其他查询的一个任务,但当然要求首先运行一个任务。它可能导致同步问题。

但实际上,听起来你正在使用某种处理队列来假定任务是自包含的。通过尝试让他们共享数据,你违背了这个概念。你的数据有多大?是否真的绝对有必要共享数据?