我必须确保运行路由的线程(和错误处理程序)保证在交换实例上看到异常集,如果该实例由许多线程共享,并且异常由其中一个线程设置。
我有一个路由步骤,在代理到实际的Web服务器之前,对输入流(jetty端点)中的数据进行按摩。对于流数据操作,我使用流管道(PipedInputStream
/ PipedOutputStream
),它们需要在每个管道元素的自己的线程中运行。每个管道元素都包含对交换的引用,如果遇到错误,则在交换机上设置异常。
这似乎工作正常。但我不认为它可以保证工作,因为exception
不是volatile
的{{1}}成员。因此,主线程不能保证工作线程在交换机上看到异常集。工作线程本身都使用我提供的DefaultExchange
作为交换属性(属性映射是ReentrantLock
)来同步它们对交换的访问。因此,工作线程之间的数据可见性不应成为问题。
但是如何为主线程做到这一点?
我查看了ConcurrentHashMap
实现以及它如何处理并行执行和聚合。据我了解,Splitter通过返回主线程以前从未见过的Splitter
交换来强制实现可见性。原子引用引用的交换在原子引用上设置后被视为只读。因此,主线程中的原子引用上的AtomicReference
可以保证看到引用的交换实例的最新版本。
我不能应用这种方法,因为它需要主线程等待工人完成处理。如果我阻塞主线程,我的工作人员将被阻止,主线程负责使用上一个get()
元素中修改后的输入流内容并将其转发到Web服务器。
我也找不到一个允许我告诉Camel实例化我自己的PipedInputStream
接口实现(带有volatile成员“异常”)的工厂机制。
(Exchange
也没有考虑到子类别,它出现了。例如DefaultException
使用私人成员DefaultException::isFailed()
代替exception
作为答案。但这是一个单独的问题。)
有没有人有其他想法?
(交叉发布here。)