2012-07-24 36 views
0

我有一个有三个线程和一个存储数据的散列图的类。其中一个线程将数据写入hashmap,另外两个线程读取数据。事情是这样的:在java中通过3个线程访问变量

public static class collector{ 
    Thread writter; 
    Thread reader1; 
    Thread reader2; 
    HashMap storage; 
    ... 
    public void write(String s){ 
    storage.put(s.hashcode(),s); 
    } 
    public String read(long hash){ 
    return storage.get(hash); 
    } 
    public Set readAll(){ 
    return storage.entrySet(); 
    } 
} 

我想第一个线程(作家)运行第一种方法(写)和reader1运行阅读和阅读器2运行readAll。但我无法找到线程访问存储(运行方法)。我如何编写线程来像这3种方法一样运行,同时他们都可以同时访问存储?

回答

1

由于类是静态的,你可以简单地调用从线程的run方法collector.write。

+0

谢谢。你救了一条命;) – Alireza 2012-07-25 00:23:34

+0

这个答案是不正确的。看看Java文档中关于“静态”类的实际意义 - 它与“静态”变量或“静态”方法无关,这就是您正在考虑的内容。 – 2012-07-25 04:07:16

+0

无论如何,这工作 – Alireza 2012-07-25 12:41:35

0

使用该变量编写单例类,并写入,读取,读取所有方法。看到您在storage对象上同步或同步这些方法。从三个线程访问这个单例类。

2

首先,为了使这个类是线程安全的,您应该使用线程安全的哈希映射实现,如java.util.concurrent.ConcurrentHashMap而不是普通的旧的java.util.HashMap

另一张海报建议在一个单例中保存一个collector实例,这相当于一个全局变量。我不会使用全局数据,而是将collector实例传递给每个线程。您可以定义Runnable的子类,该子类将collector实例作为其构造函数的参数。将collector存储在实例变量中。然后从run()方法中使用它。当你开始你的线程时,给每个对象一个不同的Runnable对象(使用合适的Thread构造函数)。

喜欢的东西:

class MyTask implements Runnable { 
    private collector myCollector; 
    public MyTask(collector _myCollector) { 
    myCollector = _myCollector; 
    } 
    public void run() { 
    // do something with myCollector 
    } 
} 
+0

它并不需要安全。因为他们中的一个只是写入散列表。另外两个阅读它。我的问题是,当我想在'collector'类中定义一个线程('implements runnable')时,我无法访问'storage'。我怎样才能访问'存储'hashmap。 – Alireza 2012-07-24 23:21:24

+0

对不起,我没有看到你编辑。 如何定义一个实例变量? – Alireza 2012-07-24 23:25:15

+1

是的,它需要是线程安全的。相信我。如果你没有使它成为线程安全的,它可能在大多数情况下工作,但有时它可能会失败。 (例如,将数据添加到“HashMap”中时,可能需要扩展Map内部使用的存储空间。如果读取器在扩展时试图遍历该结构,则可能会得到'NullPointerException'或类似的东西。) – 2012-07-24 23:25:29