2015-11-23 5 views
0

Если у меня есть игра, у которой есть поток для каждого клиента, поддерживающий информацию об этом клиенте и поток для сервера, который поддерживает информацию об игровом мире, вызовет метод на основной серверной нити из одного из клиентских потоков запускается этот метод на клиентский поток или поток сервера?Метод Java Call from Thread

+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 на поток, чтобы отслеживать, где в коде текущий поток. Если вы вызываете метод, выполнение программы происходит там, и обратно, как только метод завершится. Но он не оставит нить. Выполнение кода в потоке никогда не может перейти к другому потоку.

Единственный способ, которым вы можете выполнить свой код в другом потоке, - это заставить другой поток вызвать его для вас.

Но поскольку вы не можете напрямую вызвать другую тему, как вы можете заставить ее вызывать метод для вас? В принципе, запрограммируйте другой поток, чтобы ждать изменений в переменной, и как только он увидит изменение переменной, он может вызвать метод.

Таким образом, вызов метода сквозной резьбы на самом деле является общением через общую память, и он работает только со специальными потоками, которые запрограммированы на просмотр общей памяти. Вы не можете выполнять код в потоках, которые просто слепо делают свою вещь.

Чтобы упростить программирование этих вещей, у нас есть BlockingQueue s на Java. Любой поток может помещать вещи, а другие потоки могут ждать, когда что-то выйдет. Например, Runnable s, которые они выполняют.

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 печатать "Привет с сервера Thread." То, что serverThread делает, также называется циклом события. Потому что он ждет событий и реагирует на них.

Игры, как правило, имеют потоки, которые уже выполняют (игру). Нелегко добавить строку кода, которая проверяет события, и если она найдет некоторые, чтобы заставить их реагировать на них. У любого более крупного уже есть способ вызвать код в разных потоках.

будет вызывать метод на основном потоке сервера из одного из потоков клиента, который запускает этот метод в потоке клиента или в потоке сервера?

В клиентской нити.