我遇到了特定的Java客户端库的问题。情况如下:
我制作了一个使用该库的程序。该程序是一个名为'WorkerThread'的类,它扩展了Thread。为了启动它,我创建了一个Main类,它只包含一个启动线程的main()函数,而不是其他任何东西。 worker使用该库与服务器执行comm并获得结果。 当我想同时运行2个WorkerThreads时出现问题。我最初做的是在Main类中执行此操作:
public class Main
{
public static void main(String args[])
{
new WorkerThread().start(); // 1st thread.
new WorkerThread().start(); // 2nd thread.
}
}
当我运行它时,两个线程都会产生不合理的结果,而且第一个线程应该接收的一些结果会被第二个线程接收。
如果不是上述内容,我只是运行两个独立的进程,每个进程一个,然后一切正常。
此外:
1.在WorkerThread中没有可能导致问题的静态类或方法。我的应用程序只包含工作线程类,不包含静态字段或方法
2.该库应该可以在多线程环境中使用。在我的线程中,我只是创建一个库类的新实例,然后在其上调用方法。而已。
我的问题是: 在不知道我的实现的任何细节的情况下,上述情况和事实是否足以证明库中存在错误而不是我的程序中的错误?是否可以安全地假设库可能例如使用静态对象或库创建的线程之间共享的对象,这些线程由我的2个线程间接共享,这会导致问题?如果没有,那么在什么假设情况下bug可以来自工人类代码?
编辑:我没有说库,因为我想知道上面的事实是否可以独立于库产生我的问题的答案,但无论如何库是兔mq java客户端。每个线程创建1个连接和2个通道,并使用一个来发布数据,一个用于接收结果。编辑2:新事实:问题似乎取决于我将内容发送到队列的速率。以较慢的速率发送会降低错误结果的数量。
答案 0 :(得分:1)
答案 1 :(得分:0)
如果不了解库的作用,很难猜到。即使库设计用于多线程环境,它仍然可能需要来自调用者代码(即您)的一些额外操作才能正常工作。想象一下,库是一个数据库驱动程序,你的线程使用相同的数据库。如果线程中的DB请求没有在具有适当隔离级别的事务中正确分组,则结果可能不好。
但是,如果预计库不会与某些共享资源一起使用,那么库存在问题的可能性很高。在这种情况下,最好创建一个证明不良行为的最小测试应用程序,并将其作为错误报告提交给库的作者。
答案 2 :(得分:0)
根据您的描述,我会说问题是该库正在打开与服务器的单一连接,并且它没有做任何事情来对多个工作线程的访问进行倍增。每个流程模型的一个线程工作的原因是服务器看到分离连接并且永远不会想要混合它们。
我不知道你是否可以称这是一个bug。由于我们不了解有关图书馆的更多信息。可能的情况是,您负责传递额外的ID,该ID将随每个请求返回以找出正确的目标。或者可能是库希望您正确地序列化与它的交互。在这种情况下,您需要选择一个适当的位置来同步您的访问权限。
答案 3 :(得分:0)
您的库可能不是无条件的线程安全但有条件的线程安全。我认为如果没有图书馆所有者/供应商提供的必要文件,很难搞清楚这一点。 根据Joshua Block的说法,你的图书馆可以是有条件的线程安全的 -
像无条件线程安全一样 除了一些方法需要 外部同步安全 并发使用。例子包括 由...返回的集合 Collections.synchronized包装器, 其迭代器需要外部 同步
答案 4 :(得分:0)
不知道我的任何细节 实施,就是上面的情况 和事实足以证明那里 是库中的一个错误而不是我的错误 PROGRAMM?
没有
如果没有那么假设 这种情况可能是由臭虫发起的 工人类代码?
假设情况是,当您的两个线程从相同的队列/主题发布和接收时,您的消息排序期望既不是您的程序(例如,通过线程间协调),也不是API /库保证。