我得到了一些我必须实现的类的框架(我个人不太同意这个程序的设计,但我不会心慈手软地改变它 :( ) 并且它们以这种方式工作:
我有一个 Game
类,它实现了 Runnable
并表示一个国际象棋游戏。
一个 Server
类将有一个它跟踪的多个 Game
类的列表。
好的,这是有道理的,Game
实现了 Runnable,因此 Server
可以将每个游戏放在自己的线程中。
我对 java 的线程如何工作有点困惑。
我知道的是:
将我的 Runnable
类绑定(bind)到线程并调用 .start()
方法后,Runnable
类的 run()
方法被调用。
但是,我的 Game
类中还有一些其他方法,例如:
capturePiece()
playerMakesMove()
等等
在目前的设计中,由 Server
来处理游戏 Action 。当玩家想要捕获一 block 时,Server
将调用 game.capturePiece()
。
在这种情况下,capturePiece()
是在Game
线程上运行,还是在Server
线程上运行? (调用者的线程或被调用者的线程)
在这种情况下,run()
会做什么?
最佳答案
任何编程语言中的任何方法都在与调用方相同的线程中执行。当您调用 Thread.start()
时,它会在调用它的同一个线程中运行。
现在,您知道 Thread 的 run()
方法不在与 start
相同的线程中执行。但那是因为 start 本身并不调用 run。您将需要阅读更多关于线程的内容才能获得完整的图片,但想象一下,start 只会创建一个具有某些数据结构(Runnable
)的新线程,并且新创建的线程会查看该数据结构,标识 Runnable 并执行其 run
方法。
这确实是控制从一个线程传递到另一个线程的唯一方式:一个线程生成一些数据,另一个线程获取并处理它。控制不会从一个线程传递到另一个线程,它是线程间的通信和协调。
如果 Game
的方法被 Server
调用,那么线程将无事可做,对吗?但是相反,如果服务器不直接调用该方法而是将操作表示为数据,则 Game.run()
可以选择操作并执行它,在它自己的线程中.
现在唯一的问题是 Server
可以将数据放在哪里,以便每个在自己的线程中运行的 Game.run()
都知道从中获取数据。一种选择是使用 BlockingQueue . Server 可以将这些 Action
对象放入队列中,Game 线程可以拾取它。两者如何知道使用同一个队列?有许多不同的方法,一种是让服务器使用队列创建游戏并在其端存储 map 。如下图所示:
class Server {
Map<Game, BlockingQueue> games = ....;
void createGame() {
BlockingQueue queue = ....;
Game game = new Game(queue);
games.put(game, queue);
}
void foo() {
Game game = ....;
Action action = ....; // identify the Game
map.get(g).add(action);
}
}
class Game {
BlockingQueue _queue;
Game(BlockingQueue queue) {
_queue = queue;
}
void run() {
while (true) {
Action nextAction = _queue.take();
// perform the action
}
}
}
关于java - 如何调用 java Runnable 对象的其他方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7536641/