在Java的synchronizedList中使用break和return会产生不希望的行为。

huangapple go评论68阅读模式
英文:

Using break and return in Java's synchronizedList performs unwanted behavior

问题

我在使用Java中的synchronizedLists方面是新手,我遇到了一个问题 - 我试图做类似这样的事情:

public void foo(List<String> list) {
   List<String> syncList = Collections.synchronizedList(list);
   synchronized(syncList) {
      Iterator<String> itr = syncList.iterator();
      while(itr.hasNext()) {
         String s = itr.next();
         if(s == null) {
            return;
         }
         doStuff();
      }
   }
}

但我注意到当我运行这个代码时,doStuff() 似乎没有在列表中的每个非空项目上运行。我尝试过将 return 替换为 breakcontinue,我发现使用 break 时,doStuff() 也不会在非空的列表项目上运行。而使用 continue 时,非空的列表项目会运行 doStuff(),但由于 continue 只是跳到循环的下一次迭代,所以这个操作比预期的要昂贵得多。

为什么会出现这种情况,有什么最好的解决方法?

编辑:忘记补充一点,当我顺序运行带有 return 的代码时,它运行得很好。

英文:

I'm new at using synchronizedLists in Java, and I'm running into a problem - I'm trying to do something like this

public void foo(List&lt;String&gt; list) {
   List&lt;String&gt; syncList = Collections.synchronizedList(list);
   synchronized(syncList) {
      Iterator&lt;String&gt; itr = syncList.iterator();
      while(itr.hasNext()) {
         String s = itr.next();
         if(s == null) {
            return;
         }
         doStuff();
      }
   }
}

But I've noticed that when I run this doStuff() doesn't seem to be run on each of the non-null items in the list. I've tried experimenting with swapping out return for break and continue, and I've found that doStuff() is also not run on the non-null list items with break. With continue, the non-null list items do get doStuff() run on them but since continue just skips to the next iteration of the loop it makes this operation much more expensive than desired.

Why is this happening and what is the best workaround?

edit: Forgot to add that when I run this sequentially with return, it works fine.

答案1

得分: 0

break 语句用于退出循环。它使程序的执行跳转到循环外的第一行代码。

return 语句用于退出函数,并自然地退出包含在该函数中的循环。执行将会继续在调用该函数的地方进行。

> 使用 continue,非空的列表项会执行 doStuff(),但由于 continue 只是跳到循环的下一次迭代,这使得这个操作比预期的要昂贵得多。

我不明白 - 哪种操作比你所期望的更昂贵,以什么方式?

无论如何,这里的内容与同步或并行编程无关。Collections.synchronizedListsynchronized(syncList) 的使用是没有意义的:没有其他线程可以访问它们。

英文:

break exits the loop. It makes execution jump to the first line of code outside the loop.

return exits the function, and naturally the loop contained in the function. The execution continues where this function was called.

> With continue, the non-null list items do get doStuff() run on them but since continue just skips to the next iteration of the loop it makes this operation much more expensive than desired.

I don't understand - what operation is more expensive in what way than you desire?

Either way, nothing here has to do with synchronization or parallel programming. The way Collections.synchronizedList and synchronized(syncList) are being used is pointless: there's no way another thread can access them.

huangapple
  • 本文由 发表于 2020年4月8日 20:00:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/61100175.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定