2015-11-23 60 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所做的也稱爲事件循環。因爲它等待事件並對它們做出反應。

遊戲通常有線程已經(遊戲)循環。添加一行代碼來檢查事件並找到一些代碼來對它們做出反應是很容易的。更大的任何東西都已經可以在不同的線程中調用代碼。

會從客戶端線程之一在客戶端線程或服務器線程上運行該方法調用主服務器線程上的方法?

在客戶端線程中。