我已经阅读了很多关于多线程安全运行的内容,但老实说我不知道在这种情况下该怎么做。我正在使用API,我几乎不得不使用,这一行:
Character interactingMonster = myPlayer().getInteracting();
不幸的是,我有三个独立的线程同时运行,由于某种原因,我得到了这个例外,假设因为我在同一时间共享资源:
[ERROR][06/18 09:54:56 AM]: Uncaught exception!
java.lang.ArrayIndexOutOfBoundsException: 32767
at org.api.Players.getLocalPlayer(Players.java:39)
我遇到多个线程的所有其他问题,我已经修复了使用线程安全的数据类型,比如AtomicLong和CopyOnWriteArrayList,但在这种情况下,我需要一些建议。我需要找到一种方法来解决这个问题,而不必忽略使用多线程的好处。
任何提示?
PS。我无法访问myPlayer().getInteracting();
它只是API,而且它的类被混淆了。
答案 0 :(得分:1)
如果你调用的API不是线程安全的(文档应该告诉你,你的经验会暗示它不安全),那么你需要同步访问它,所以只有一个线程可以一次调用它。如果调用总是在同一个方法中进行(并且其中没有其他事情发生),那么您可以使整个方法同步。或者,您可以拥有一个同步的代码块,在这种情况下,您必须有一个要使用的对象,例如:
synchronized (myObject) {
// call to non-thread-safe API
}
并确保对所有对同一api的调用使用相同的myObject。
这将对性能产生影响,并且意味着您必须开始担心潜在的死锁。有很多有关java和线程安全的教程,使用了“同步”和“#39;同步”。以及最近添加的Lock对象。
答案 1 :(得分:0)
您始终可以将该行代码与目标对象同步开始:
Character interactingMonster;
synchronized (myPlayer){
interactingMonster = myPlayer().getInteracting();
}
答案 2 :(得分:0)
了解同步http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html
我是一个视觉人,所以这是一个有趣的同步我喜欢使用的例子,我觉得解释同步是如何工作的。代码基本上由2种不同的线程类型组成,一种是同步的,另一种不是。每个线程类型都打印一个字符串,后跟一个从0增加到9的整数。
在输出中,您会在一开始就看到foo
和bar
的大字体,这些消息只会在foo 9
和{{ 1}},这是同步线程。未同步的帖子是bar 1
和hello
,您会看到这些消息混杂在一起。
<强>输出强>:
world
<小时/> 的代码强>
foo 0
foo 1
foo 2
foo 3
foo 4
foo 5
foo 6
foo 7
foo 8
foo 9
bar 0
bar 1
bar 2
bar 3
bar 4
bar 5
bar 6
bar 7
bar 8
bar 9
world 0
hello 0
hello 1
world 1
hello 2
world 2
hello 3
world 3
hello 4
world 4
hello 5
world 5
hello 6
world 6
hello 7
world 7
hello 8
world 8
world 9
hello 9