我正在编写一段代码,如果它们的键相同,它们应该组合散列表/散列映射的值。但是,当我尝试使用迭代器执行此操作时,它会抛出java.util.ConcurrentModificationException
。令人惊讶的事实是,这种情况仅在某些情况下发生,而在其他情况下则完全发挥作用。我的代码如下:
启动流程的行。从onPostExecute
的{{1}}开始:
AsyncTask
ListFragment.addtolist(getdataformap());
的片段:
ExpandableListView
堆栈:
public static class ListFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static CustomMap1 datapforputcustom ;
public static ExpandableListView expandablelistview;
public static CustomExpandableListAdapter expandableadapter;
public static Hashtable<Fitems, List<Fnitems>> datapforput = new Hashtable<>();
public static List<Fitems> mainforput = new ArrayList<>();
public static View view;
public static Context getha;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = inflater.inflate(R.layout.activity_listfragment, container, false);
//doddata();
expandablelistview = (ExpandableListView) view.findViewById(R.id.expandableListView);
expandableadapter = new CustomExpandableListAdapter(((Result) getActivity()).getha(), mainforput, datapforput);
expandablelistview.setAdapter(expandableadapter);
getha = ((Result) getActivity()).getha();
return view;
}
@Override
public void onStart() {
super.onStart();
Permutation.finallist = new ArrayList<>();
Single_Permutation.singlelist = new ArrayList<>();
/* doddata();
expandablelistview = (ExpandableListView) view.findViewById(R.id.expandableListView);
expandableadapter = new CustomExpandableListAdapter(((Result)getActivity()).getha(),mainforput,datapforput);
expandablelistview.setAdapter(expandableadapter);*/
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static class CustomMap1 extends Hashtable<Fitems, List<Fnitems>> {
@Override
public List<Fnitems> put(Fitems value, List<Fnitems> valuelist) {
List<Fnitems> oldlist = new ArrayList<>();
Fitems oldkey =value;
String tester="";
for (Entry<Fitems, List<Fnitems>> entry : entrySet()) {
Log.e("LIST",(entry.getKey().getName()+(value.getName())));
if (value.getName().equals(entry.getKey().getName())) {
tester = "ojfagsbou";
oldkey = entry.getKey();
oldlist.addAll(entry.getValue());
remove(entry.getKey());
}
}
// combine your keys as you wish
List<Fnitems> newvaluelist = new ArrayList<>();
if (!"".equals(tester)) {
System.out.println(oldkey.getName()+"oldkey");
newvaluelist.addAll(oldlist);
newvaluelist.addAll(valuelist);
} else {
newvaluelist.addAll(valuelist);
System.out.println(oldkey.getName()+"oldkey");
mainforput.add(oldkey);
}
return super.put(oldkey, newvaluelist);
}
}
public static void doddata() {
/* Fitems fitems1 = new Fitems();
Fitems fitems2 = new Fitems();
Fnitems fnitems1 = new Fnitems();
Fnitems fnitems2 = new Fnitems();
Fnitems fnitems3 = new Fnitems();
Fnitems fnitems4 = new Fnitems();
fitems1.setName("AAA");
fitems2.setName("BBB");
fnitems1.setName("AAAa");
fnitems2.setName("AAAb");
fnitems3.setName("BBBa");
fnitems4.setName("BBBb");
List<Fnitems> listfnitem1 = new ArrayList<>();
List<Fnitems> listfnitem2 = new ArrayList<>();
listfnitem1.add(fnitems1);
listfnitem1.add(fnitems2);
listfnitem2.add(fnitems3);
listfnitem2.add(fnitems4);*/
mainforput=new ArrayList<>();
datapforputcustom = new CustomMap1();
datapforput = new Hashtable<>();
ArrayList<String> strind = new ArrayList<>();
for(Map.Entry<String,Map<String,Integer>> entry1 : Result.cart_names1.entrySet()){
strind.add(entry1.getKey());
}
Log.e("ERROR", "thisis the list for god's sake " + Result.couldthis+datapforput.toString());
if (Result.couldthis.size() > 0) {
for (int i = 0; i < (Result.couldthis).size(); i++) {
Fitems fitems3 = new Fitems();
fitems3.setName(Result.couldthis.get(i));
Fnitems fnitems5 = new Fnitems();
fnitems5.setName(strind.get(i));
List<Fnitems> listfnitem3 = new ArrayList<>();
listfnitem3.add(fnitems5);
Log.e("RE",fitems3.getName()+" "+listfnitem3.get(0).getName());
datapforput.put(fitems3,listfnitem3);
}
}
datapforputcustom.putAll(datapforput);
Log.e("UGF",datapforputcustom+" cusom");
//datapforput.put(fitems1, listfnitem1);
// datapforput.put(fitems2, listfnitem2);
// mainforput.add(fitems1);
// mainforput.add(fitems2);
}
public static ListFragment newInstance() {
ListFragment fragment = new ListFragment();
Log.e("ERROR", "man .... " + fragment.getTag());
return fragment;
}
public static void addtolist(ArrayList<String> dataforputting) {
Log.e("ERROR", "thisis the list 3" + (dataforputting));
//if (expandableadapter != null){
expandableadapter.clear();//}
Log.e("INFO", "This is mainforput" + mainforput + "This is dataforput" + datapforput);
doddata();
Log.e("INFO", "This is mainforput" + mainforput.get(0).getName() + "This is dataforput" + datapforputcustom);
expandableadapter = new CustomExpandableListAdapter(getha, mainforput, datapforputcustom);
expandablelistview.setAdapter(expandableadapter);
}
}
百万提前谢谢!
答案 0 :(得分:0)
请阅读:https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Hashtable.html
Hashtable
的开头说明涵盖了您遇到的ConcurrentModificationException
;文档声明Hashtable
的迭代器是快速失败的,并且只要迭代器和迭代器下的基础ConcurrentModificationException
更改未用于进行这些更改,就会抛出Hashtable
。 / p>
在堆栈中,列出了putAll()
- 因此它正在修改底层结构并导致迭代器失败。无论如何你可以协调这两个事件不同时发生吗?如果你能找到一种方法,那么我认为你将解决问题。
答案 1 :(得分:0)
发生ConcurrentModificationException是因为你没有锁定对HashTable的REMOVE方法的访问,因此有人可以在你的重写PUT方法中迭代HashTable时插入和删除项目。
请检查我的课程,这个可以随时重现您的错误。修复程序可以在&#34; CustomMapImproved&#34;中找到。类。
import java.util.concurrent.locks.ReentrantLock;
public class TestHashTable {
public static class CustomMap1 extends Hashtable<String, List<String>> {
@Override
public List<String> put(String value, List<String> valuelist) {
List<String> oldlist = new ArrayList<>();
String oldkey = value;
String tester="";
for (Map.Entry<String, List<String>> entry : entrySet()) {
if (entry.getValue().get(0)!=null
&& value.equals(entry.getValue().get(0))) {
tester = "arbitrary";
oldkey = entry.getKey();
oldlist.addAll(entry.getValue());
remove(entry.getKey());
}
}
// combine your keys as you wish
List<String> newvaluelist = new ArrayList<>();
if (!"".equals(tester)) {
//System.out.println(oldkey.getName()+"oldkey");
newvaluelist.addAll(oldlist);
newvaluelist.addAll(valuelist);
} else {
newvaluelist.addAll(valuelist);
}
return super.put(oldkey, newvaluelist);
}
}
public static class CustomMapImproved extends Hashtable<String, List<String>> {
private final Lock lock = new ReentrantLock();
@Override
public List<String> put(String value, List<String> valuelist) {
lock.lock();
try{
List<String> oldlist = new ArrayList<>();
String oldkey = value;
String tester="";
Iterator<Map.Entry<String, List<String>>> iterator = entrySet().iterator();
java.util.Map.Entry<String, List<String>> entry;
while (iterator.hasNext()) {
entry = iterator.next();
if (entry.getValue().get(0) != null && value.equals(entry.getValue().get(0))) {
tester = "arbitrary";
oldkey = entry.getKey();
oldlist.addAll(entry.getValue());
iterator.remove();//use this instead of remove(Object);
}
}
// combine your keys as you wish
List<String> newvaluelist = new ArrayList<>();
if (!"".equals(tester)) {
//System.out.println(oldkey.getName()+"oldkey");
newvaluelist.addAll(oldlist);
newvaluelist.addAll(valuelist);
} else {
newvaluelist.addAll(valuelist);
}
return super.put(oldkey, newvaluelist);
}finally{
lock.unlock();
}
}
@Override
public List<String> get(Object obj){
lock.lock();
try{
return super.get(obj);
}finally{
lock.unlock();
}
}
@Override
public List<String> remove(Object obj){
lock.lock();
try{
return super.remove(obj);
}finally{
lock.unlock();
}
}
}
public static void main(String[]args){
//final Hashtable<String,List<String>> map = new CustomMap1();
final Hashtable<String,List<String>> map = new CustomMapImproved();
final List<Thread> tList = new ArrayList<Thread>();
final int reps = 1000;
int thread = 100;
for(int i=0;i<thread; i++){
final int idx = i;
Thread t = new Thread(new Runnable(){
public void run(){
for(int i=0;i<reps;i++){
if(idx%2==0){
List<String> list = new ArrayList<String>();
list.add("value"+idx);
map.put("value"+idx,list);
}
else{
map.remove("value"+idx);
}
}
}
});
t.start();
tList.add(t);
}
for(Thread t : tList){
try {t.join();} catch (InterruptedException e) {}
}
}
}