2015-11-23 61 views
0

如果我有一个游戏,每个客户端都有一个线程,维护关于该客户端的信息以及维护关于游戏世界的信息的服务器的线程将调用主服务器线程上的方法从其中一个客户端线程在客户端线程或服务器线程上运行该方法?来自线程的Java方法调用

+1

被调用的方法将始终在调用者的上下文中执行。这意味着方法调用永远不会改变线程。这就是没有人调用Thread.run方法的原因。你启动它,线程开始在它的上下文中调用方法本身。无论您命名包含方法服务器线程或客户端线程的地方(类)是不相关的 – zapl

+0

“从一个客户端线程调用主服务器线程上的方法” - 这不完全合理,但听起来像您可能会问一些类似[这个问题](http://stackoverflow.com/questions/24441751/if-a-method-belongs-to-another-class-that-extends-thread-but-is-called-from -The)。 –

回答

0

线程就像字符串的字面意思一串命令。一台计算机每个线程有一个单独的instruction pointer以跟踪线程当前所在的代码的位置。如果你调用一个方法,那么程序执行跳转到那里,一旦方法结束,就返回。但它不会离开这个线程。在线程中执行的代码永远不会跳转到不同的线程。

你可以让你的代码在不同的线程中执行的唯一方法是让其他线程为你调用它。

但是既然你不能直接调用其他线程,你怎么能让它为你调用一个方法?基本上,编程另一个线程来等待变量的变化,一旦它看到变量改变它可以调用该方法。

因此,跨线程方法调用实际上是通过共享内存进行通信的,它只能用于编程查看共享内存的特殊线程。你不能在线程中执行代码,只是盲目地做他们的事情。

为了便于编程这些东西,我们在Java中有BlockingQueue s。任何线程都可以放入东西,其他线程可以等待一些东西出来。例如他们执行的Runnable

final BlockingQueue<Runnable> codeQueue = new LinkedBlockingQueue<>(); 
    Thread serverThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (!Thread.interrupted()) { 
       try { 
        Runnable code = codeQueue.take(); 
        // call code in my context. 
        code.run(); 
       } catch (InterruptedException e) { 
        Thread.currentThread().interrupt(); 
       } 
      } 
     } 
    }); 
    Thread clientThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      codeQueue.add(new Runnable() { 
       @Override 
       public void run() { 
        System.out.println("Hello from Server Thread."); 
       } 
      }); 
     } 
    }); 

在这个例子中,clientThread导致serverThread打印 “从服务器线程你好。” serverThread所做的也称为事件循环。因为它等待事件并对它们做出反应。

游戏通常有线程已经(游戏)循环。添加一行代码来检查事件并找到一些代码来对它们做出反应是很容易的。更大的任何东西都已经可以在不同的线程中调用代码。

会从客户端线程之一在客户端线程或服务器线程上运行该方法调用主服务器线程上的方法?

在客户端线程中。