值未插入Hashmap

时间:2016-01-24 09:02:07

标签: java

public class FileReaderServer implements Runnable
{
    private Map<String, String> mapp = new HashMap<String, String>();

    public void searchWords()
    {
        try
        {
            BufferedReader br = new BufferedReader(new FileReader(input));
            while ( (line = br.readLine()) != null )
            {
                boolean success = tree.search(line);
                if ( success )
                    mapp.put(line, "TRUE");
                else
                    mapp.put(line, "FALSE");
            }
        }
        catch( Exception ex )
        {
            System.out.println( ex );
        }
    }

    public void run()
    {
        searchWords();
    }

    public void printMap()
    {
        Iterator it = mapp.entrySet().iterator();
        while ( it.hasNext() ) 
        {
            Map.Entry pair = (Map.Entry)it.next();
            System.out.println(pair.getKey() + " = " + pair.getValue());
        }
    }

    public static void main( String[] args )
    {
        try
        {
            FileReaderServer server = new FileReaderServer("keywords.txt");
            server.createTree();

            Thread t1 = new Thread(new FileReaderServer());
            Thread t2 = new Thread(new FileReaderServer());
            Thread t3 = new Thread(new FileReaderServer());             

            t1.start();
            t2.start();
            t3.start();

            t1.join();
            t2.join();
            t3.join();

            server.printMap();
        }
        catch( Exception ex )
        {
            System.out.println(ex);
        }
    }

这是我原来课程的简化版,足以说明我相信的问题。 (如果没有,请让我知道粘贴一些代码。)

问题在&#34; printMap&#34;什么都没有印刷。但是,代码已达到

boolean success = tree.search(line);
if ( success )
{
    System.out.println(line + "TRUE");   // This is getting printed.
    mapp.put(line, "TRUE");
}
else
    mapp.put(line, "FALSE");

编辑: - 这里还有一个问题。我试图制作searchWords synchronized。但是,我将不同的实例传递给每个创建的线程。因此,同步是对象或类的属性。即这些线程中是否有任何一个可以同时执行该函数。

4 个答案:

答案 0 :(得分:2)

将FileReaderServer的另一个实例传递给每个线程:

        Thread t1 = new Thread(new FileReaderServer());
        Thread t2 = new Thread(new FileReaderServer());
        Thread t3 = new Thread(new FileReaderServer());   

但你试图从以下方面获取价值:

        FileReaderServer server = new FileReaderServer("keywords.txt");

...

        server.printMap();

如果您将服务器实例传递给这三个线程中的每一个 - 由于 java.util.HashMap 的非同步性质,您将获得意外行为。将其替换为 java.util.concurrent.ConcurrentHashMap

UPD1 如果您将 searchWords()标记为同步 - 您将失去并发的所有好处,因为所有3个线程都将执行按顺序 searchWords()

所以我仍然坚持使用 ConcurrentHashMap

private Map<String, String> mapp = new ConcurrentHashMap<String, String>();

或者你可以简单地用 Collections.synchronizedMap(...)包装 HashMap 实例,如下所示:

private Map<String, String> mapp = Collections.synchronizedMap(new HashMap<String, String>())

答案 1 :(得分:2)

您的问题是,您尝试从server获取行。但服务器对象将无法启动。你必须这样开始你的线程:

Thread t1 = new Thread(server);
Thread t2 = new Thread(server);
Thread t3 = new Thread(server);   

在这种情况下,你必须考虑良好的同步。

答案 2 :(得分:1)

您正在打印HashMap变量引用的FileReaderServer个实例的server成员,但这不是您要添加条目的HashMap

您要将条目添加到传递给您正在创建的HashMap的{​​{1}}个实例的FileReaderServer

如果希望Thread的所有实例共享mapp,您可能希望FileReaderServer为静态。但是,如果您这样做,可能会遇到同步问题,因此您可能应该使用ConcurrentHashMap

答案 3 :(得分:1)

采用String文件名的构造函数在哪里。创建一个构造函数,该构造函数将String文件名作为参数。

FileReaderServer server = new FileReaderServer("keywords.txt");

您在哪里初始化变量输入:

BufferedReader br = new BufferedReader(new FileReader(input));

创建线程时,FileReaderServer不知道要读取哪个文件。

Thread t1 = new Thread(new FileReaderServer());