Java Pattern::Aspreditate线程安全吗
我检查了Java8文档,发现这个类有这个方法 我在查看StackOverflow,但没有发现任何与线程安全相关的内容 我知道模式类是线程安全的,正如文档所说 此类的实例是不可变的,可供多个并发线程安全使用。Matcher类的实例对于这种使用是不安全的Java Pattern::Aspreditate线程安全吗,java,java-8,matcher,Java,Java 8,Matcher,我检查了Java8文档,发现这个类有这个方法 我在查看StackOverflow,但没有发现任何与线程安全相关的内容 我知道模式类是线程安全的,正如文档所说 此类的实例是不可变的,可供多个并发线程安全使用。Matcher类的实例对于这种使用是不安全的 但是,asPredicate方法生成的谓词会发生什么情况?Matcher没有方法asPredicate;这是模式。同样地,返回的谓词也是线程安全的-它将作为新的匹配器返回,谓词将从中生成-因为文档说它是不可变的 Matcher不是线程安全的,但是P
但是,asPredicate方法生成的谓词会发生什么情况?
Matcher
没有方法asPredicate
;这是模式
。同样地,返回的谓词
也是线程安全的-它将作为新的匹配器
返回,谓词
将从中生成-因为文档说它是不可变的 Matcher
不是线程安全的,但是Pattern
是线程安全的。关于<>代码> AsExpDead()<代码>,您可以认为它是线程安全的,因为它本身被定义为多个并发线程使用的安全性: 此类的实例是不可变的,可供多个用户安全使用 并发线程。Matcher类的实例对于 这样的用途 正如Holger所强调的,由
Pattern.asPredicate()
返回的谓词
没有作为线程安全(或相反)记录,但它的实现证明它是:
public Predicate<String> asPredicate() {
return s -> matcher(s).find();
}
可以这样做:
boolean isFound = pattern.asPredicate().test(myString);
所以这里的新事物是,您可以在流或任何接受谓词的方法中传递谓词。这使得意图更加清晰:不需要操纵模式
,而是操纵谓词
Pattern pattern = ...;
...stream().filter(o-> pattern.matcher(o).find());
可替换为:
Predicate<String> predicate = pattern.asPredicate();
List<String> strings = ...;
strings.stream().filter(predicate).(...);
//or
strings.stream().filter(pattern.asPredicate()).(...);
谓词=pattern.asPredicate();
列表字符串=。。。;
strings.stream().filter(谓词)。(…);
//或
strings.stream().filter(pattern.asPredicate()).(…);
谓词只提供一个值。它没有可以更改的状态。因此,它是不可变的,因此是线程安全的。线程安全性大部分都没有文档记录。但这可能会有所帮助:@eugeneah好的。如果asPredicate
方法确实是Matcher
的一种方法,那么您可能是对的。但事实并非如此!这是一种线程安全的模式方法。@Seelenvirtuose从概念上讲你是对的:谓词不应该有状态,甚至不应该改变任何状态。但是它的错误使用可能会改变谓词体使用的对象的状态,从而破坏线程安全asPattern()
当然不重要。@davidxxx你说得对。我在模式
(vs.匹配器
)的上下文中发表了我的评论,后来意识到OP确实搞乱了这两个类。我不能再编辑评论了,所以我保留原样。没错,编辑时有点小错误。我修好了。感谢您的示例pattern.matcher(myString).find()
显示实际操作必须通过matcher
。Java 8中没有指定创建的谓词是每次创建一个新的匹配器(这将是线程安全的),还是创建一个并重用它(这不会)。谢天谢地,.@Holger确实没有直接指定,但模式类本身声明:“这个类的实例是不可变的,可以由多个并发线程安全使用。“多个并发线程安全使用”假设所有实例方法都是线程安全的,所以asPredicate()
是。关于JDK 11 javadoc,我想你提到的部分是“好像它创建了一个匹配器”。我觉得“好像”的表述有点烦人,因为模棱两可。是的,asPredicate()
的调用对于每个类文档来说是线程安全的,匹配器(…)的调用也是线程安全的
。但正如匹配器(…)
示例所示,这并没有说明返回的对象。返回的谓词是否线程安全,只能从它等价于s->matcher.find()的语句中派生出来,但是如果你认为太弱,你必须修改你的答案,因为<代码>模式是线程安全的,它不使用模式来说明对象,比如<代码> Matcher <代码>或<代码>谓词< /代码>实现。霍格尔有趣的是,我只从实现中扣除了这个,但不是吗?意思是说,Matcher::Matcher
必须始终返回一个新实例?确实如此,但是为这个模式返回一个新的Matcher就足够了吗?;我猜这里的单词new是字面意思。@Eugene你的意思是pattern::Matcher
,但是是的,“创建一个Matcher…”和“@returna new Matcher…”必须从字面上理解。其他一切都会破坏线程安全可重用性的目的。正如类doc所说,“…那么多匹配器可以共享相同的模式”。
Predicate<String> predicate = pattern.asPredicate();
List<String> strings = ...;
strings.stream().filter(predicate).(...);
//or
strings.stream().filter(pattern.asPredicate()).(...);