为什么并发哈希映射在由两个线程访问时正常工作,一个使用clear(),另一个使用putifAbsent()方法?

时间:2014-02-22 04:46:21

标签: java multithreading clear concurrenthashmap

我正在使用并发哈希映射实现一个应用程序。需要一个线程将数据添加到CHM中,而另一个线程复制当前在CHM中的值并使用clear()方法将其擦除。当我运行它时,在执行clear()方法之后,CHM始终保持为空,尽管另一个线程继续向CHM添加数据。 有人能告诉我为什么会这样,并帮助我找到解决方案。

这是将数据添加到CHM的方法。从线程中调用此方法。

import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
public static ConcurrentMap<String, String> updateJobList = new ConcurrentHashMap<String, String>(8, 0.9f, 6);   
public void setUpdateQuery(String ticker, String query)
        throws RemoteException {  
    dataBaseText = "streamming";  
   int n = 0;  
    try {  
         updateJobList.putIfAbsent(ticker, query);  
        }  
    catch(Exception e)
    {e.printStackTrace();}   
     ........................
 }

另一个线程每分钟调用一次track_allocation方法。

public void track_allocation()
{
        class Track_Thread implements Runnable {
            String[] track;
            Track_Thread(String[] s)
            {
                track = s;
            }
            public void run()
            {

            }
            public void run(String[] s)
            {
                  MonitoringForm.txtInforamtion.append(Thread.currentThread()+"has     started runnning");
                String query = "";
                track = getMaxBenefit(track);
                track = quickSort(track, 0, track.length-1);
                for(int x=0;x<track.length;x++)
                {
                    query = track[x].split(",")[0];
                    try
                    {
                    DatabaseConnection.insertQuery(query);
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
        joblist = updateJobList.values();
         MonitoringForm.txtInforamtion.append("\nSize of the joblist is:"+joblist.size());
        int n = joblist.size()/6;
        String[][] jobs = new String[6][n+6];
          MonitoringForm.txtInforamtion.append("number of threads:"+n);
        int i = 0;
        if(n>0)
        {
            MonitoringForm.txtInforamtion.append("\nSize of the joblist is:"+joblist.size());
           synchronized(this)
           {
            updateJobList.clear();
           }
            Thread[] threads = new Thread[6];
           Iterator it = joblist.iterator();
           int k = 0;
            for(int j=0;j<6; j++)
            {    
                for(k = 0; k<n; k++)                    
                { 
                    jobs[j][k] = it.next().toString();                   

                    MonitoringForm.txtInforamtion.append("\n\ninserted into queue:\n"+jobs[j][k]+"\n");

                }
                if(it.hasNext() && j == 5)
                {
                    while(it.hasNext())
                    {
                        jobs[j][++k] = it.next().toString();
                    }
                }
                threads[j] = new Thread(new Track_Thread(jobs[j]));
                threads[j].start();

            }
        }
}

1 个答案:

答案 0 :(得分:3)

我可以看到一个明显的错误。这是您的Track_Threadrun方法的实现。

    public void run()
        {

        }

所以,当你这样做时:

   threads[j] = new Thread(new Track_Thread(jobs[j]));
   threads[j].start();

.....线程开始,然后立即结束,完全没有做任何事情。永远不会调用您的run(String[])方法!


此外,您在迭代地图然后在其他线程同时添加时清除它的方法可能会导致偶尔从地图中删除条目,而迭代实际上看不到它们。


虽然我引起了您的注意,但您的代码中存在很多样式错误:

  • 缩进是一团糟。
  • 您错误地命名了您的类:它不是一个线程,该标识符忽略了Java标识符规则。
  • 您在语句中使用空格是不一致的。

这些事情使你的代码难以阅读......坦率地说,他们让我试图真正理解它。