Java 如果一个库不是多线程库,该怎么办?
我想多线程应用程序,但我使用的一个库不支持多线程(我不知道什么是正确的词?synchronized?) 我有什么选择 据我所知,java中的线程和进程(Runtime.exec)之间没有任何东西(jvm中没有类似于独立“java进程”的抽象) 你会怎么处理 编辑Java 如果一个库不是多线程库,该怎么办?,java,concurrency,Java,Concurrency,我想多线程应用程序,但我使用的一个库不支持多线程(我不知道什么是正确的词?synchronized?) 我有什么选择 据我所知,java中的线程和进程(Runtime.exec)之间没有任何东西(jvm中没有类似于独立“java进程”的抽象) 你会怎么处理 编辑 再次感谢您提供的所有答案,一个级别的间接寻址就可以做到这一点。您可以确保所讨论的库一次只能从一个线程使用。如果它包含可实例化的类,一种可能是将它们保存在中 或者,您可以围绕它构建线程安全 这些方法也可以结合使用,例如,您可以将库包装在一
再次感谢您提供的所有答案,一个级别的间接寻址就可以做到这一点。您可以确保所讨论的库一次只能从一个线程使用。如果它包含可实例化的类,一种可能是将它们保存在中 或者,您可以围绕它构建线程安全 这些方法也可以结合使用,例如,您可以将库包装在一个类中(在本例中,它将是一个类),该类本身不是线程安全的,但是您可以一次从单个线程访问其实例
更新:正如@Wim所指出的,如果库管理全局状态,则必须使用线程安全包装,以确保线程之间的更改可见。我将创建一个外观,而不是直接使用库。然后,Facade应该同步到库的连接/调用 比如:
External Call External Call External Call
| | |
----------------------------------
Wrapper
|
Library
更新:
外观可能是错误的设计模式,因为它用于隐藏功能。
包装器应该用作设计模式我会编写一个瘦包装器,其中所有相关方法都是同步的,然后我会在代码中的任何地方使用它,而不是直接使用库的类和方法。我会首先评估,对于库的哪些部分,这实际上是必要的
有时,也可以为每个线程使用库对象的单独实例。但是在这种情况下,实例不能在线程之间共享。很多情况取决于库的大小和使用它的目的。要做的第一件事是评估实际存在并发问题的地方。您在多个线程中使用库并不意味着它不能在多个线程中使用。在API中查找明确表示“这不是线程安全的”的项目,如果要使用API的该部分,则需要自己进行同步。最简单的解决方案是创建一个同步所有方法的包装器类。例如,查看收集实用程序(如Collections.synchronizedList等)中的源代码。查看Collections API中如何解决类似问题。默认情况下,并非所有集合都是线程安全的 但是当你需要一个线程安全的集合时,你只需要使用它就可以了
Collections.synchronizedCollection(unsafeCollection)
实现对用户是隐藏的,它不是API的一部分。您也可以这样做。Facade是一种针对稍有不同问题的设计模式,它应该是一个包装器或适配器。Facade应该隐藏功能,在这种情况下还应该隐藏其他类。也许你是对的,它也可能是一个包装器。你要找的词是“线程安全的”。@Stephen C:谢谢。我无法回忆它。作为同步方法的替代方法,您可以使用锁(例如ReentrantReadWriteLock)来减少瓶颈,前提是您了解库的行为,并且可以决定何时使用ReadLock和WriteLock。@Sebastian:如果您对库有足够的了解,可以这样做。可能需要注意的是,如果这导致多个锁对象,那么显然您还必须确保避免死锁。第一个实际上意味着第二个。您需要内存屏障来确保缓存一致性(每个线程在库中的任何全局状态上都应该具有相同的视图)。注意,尽管未考虑线程安全的库很少在其API文档中明确表示“这不是线程安全的”:-(