Java 8 Stream修改mutable var

时间:2016-01-26 14:57:36

标签: java multithreading java-8 java-stream

我试图了解parallelStreams的工作原理。让我们考虑以下示例:

public class Person {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }  
    }

主要方法:

public static void main(String[] args) {
    final Person person = new Person();
    person.setName("John Doe");
    List<String> myList = Arrays.asList("1","2","3","4","5","6");
    myList.forEach((String element) -> {
        person.setName(person.getName()+element);
        System.out.println(person.getName());
    });
}

结果将是:

John Doe1
John Doe12
John Doe123
John Doe1234
John Doe12345
John Doe123456 

如果我将其更改为parallelStream(),结果可能是这样的:

John Doe4
John Doe41
John Doe415
John Doe4156
John Doe41562
John Doe415623  

是否可能会附加少于6位的数字?例如,如果两个Threads在开头的同时读取值John Doe。 One Thread追加&#34; 1&#34;和另一个线程a&#34; 2&#34;。再次设置名称时,其中一个会覆盖另一个名称。

修改:

我问的原因是:我有一个带有一些占位符的字符串。我编写了自己的Spliterator来提取占位符。此外,我有一个地图,提供占位符的替代品。所以我应用一个过滤器来检查每个占位符是否有替换。之后,我替换字符串。我认为如果以并行模式运行,在最后一步中替换String将无法正常工作。

1 个答案:

答案 0 :(得分:3)

是的,这是可能的。您只需要在Stream中添加更多元素以使其更频繁地发生。

考虑一下:

public static void main(String[] args) {
    final Person person = new Person();
    person.setName("John Doe");
    List<String> myList = IntStream.rangeClosed('a', 'z').mapToObj(c -> String.valueOf((char) c)).collect(Collectors.toList());
    myList.parallelStream().forEach((String element) -> {
        person.setName(person.getName()+element);
        System.out.println(person.getName());
    });
}

与您的代码相同,但这次我们在字母表中附加所有小写字母。我刚刚运行它,最后的结果在哪里:

John Doengopqrswxyztuvabchijkl
John Doengopqrswxyztuvabchijklm
John Doengopqrswxyztuvabcd
John Doengopqrswxyztuvabcde
John Doengopqrswxyztuvabcdef

这意味着你所描述的效果肯定正在发生。

我们需要添加更多元素的原因只是为了增加这种效果发生的可能性。

重要提示:您在问题中没有说为什么您想要这个。但请记住,改变外部变量通常是你想要首先避免的。