2017-01-17 2 views
0

Я пишу сервер в java. для этого вопроса позволяет сказать следующее: сервер может принимать несколько клиентов, каждый из которых в своем потоке. каждый клиент, однажды подключенный, вызывает один метод на сервере, который рисует какой-то графический объект. только один экземпляр метода должен быть активным сразу. в случае, если этот метод активен одновременно в нескольких потоках, результатом будет то, что рисованный объект будет скремблирован. для выполнения метода требуется около 100 мс. , чтобы предотвратить одновременное обращение к нескольким потокам, я добавил статическое поле класса, которое после вызова этого метода обновляется, чтобы отметить, что этот метод активен, и как только метод завершает работу, он обновляет свойство, чтобы отметить, что этот метод неактивен. каждый поток вызывает этот метод, но первый способ - проверка значения этого поля, и если он указывает, что еще один экземпляр метода уже выполняется, он помещает этот поток в сон в течение короткого времени, и как только он просыпается, он периодически проверяет значение поля, и как только значение указывает, что еще один поток завершает выполнение этого метода, затем продолжается другой поток, обновляет значение этого поля, чтобы указать, что он выполняется, а затем выполняется и снова обновляет его, чтобы указать, что он завершен. , это относится к каждому потоку, когда он вызывает метод.Как управлять доступом нескольких потоков к объекту в java?

Этот подход улучшил случаи, когда произошло столкновение, но оно не полностью устранило его. это потому, что требуется некоторое время, так как какой-то поток обнаруживает, что другой поток завершен, пока он не обновит параметр, чтобы указать, что он теперь выполняется снова. это время очень короткое, меньше 1 мс, но все же возможно возникновение столкновения, то есть для более чем одного потока, чтобы обнаружить, что этот метод не выполняется. так как возможно, что, поскольку один поток обнаруживает, что метод не выполняется, пока он не помечает его как выполняющий, что в среднем время другой поток также обнаруживает этот метод как не выполняющий.

я знаю, что это могло бы шов запутанным, поэтому я подготовил небольшой пример для вас, чтобы лучше понять меня:

public class some_class_acessed_by_multiple_threads 
{ 
    private static volatile java.lang.Boolean lock_access; 
    static 
    { 
     lock_access = false; 
    } 
    public static void some_method_called_by_multiple_threads() throws java.lang.InterruptedException 
    { 
     //detection. 
     while(lock_access) 
     { 
      java.lang.Thread.sleep(64); 
     } 
     //locking access to other threads. 
     lock_access =true; 
     some_method_which_must_not_be_active_in_multiple_threads_at_once(); 
     //once execution completes, unlocking access to other threads. 
     lock_access =false; 
    } 
    private static void some_method_which_must_not_be_active_in_multiple_threads_at_once() 
    { 
     //draw some object. 
    } 
} 

если я использовать логику, как в данном примере выше, чтобы предотвратить доступ к методу более чем одной нити сразу же он отлично работает для небольшого количества потоков. если подключено 1, 2, 5, 10, 50 клиентов, столкновений не происходит.

, но если я могу сказать, что 1000 клиентов (что означает 1000 потоков, борющихся за доступ к этому методу для рисования объектов) или более, столкновения все еще начинают происходить очень часто. , как вы можете видеть из моего примера, из строки «обнаружение» заканчивается выполнение до тех пор, пока строка «блокировка доступа ...» не завершится, она пройдет некоторое время. вероятно, время в микросекундах, но все же проходит некоторое время.

так что у меня есть вопрос, как я могу улучшить свой код выше, так что даже 1000 потоков, борющихся за доступ к методу рисования объектов, могут вызвать столкновение?

Благодарим вас за любые предложения.

+3

Вы можете использовать 'synchronized' или' Lock' – JonahCui

+0

. Замечание: пожалуйста, следуйте широко распространенным соглашениям о кодировании в Java: underscore является ** только ** для констант, а имена классов начинаются с верхнего регистра. – GhostCat

+0

Другое, что действительно странно: у вас есть какая-то передовая проблема, но ваш дизайн использует статические вызовы повсюду ?! – GhostCat

ответ

1

Вы пробовали встроенное ключевое слово java synchronized?

private static void some_method_which_must_not_be_active_in_multiple_threads_at_once() 

становится

private static synchronized void some_method_which_must_not_be_active_in_multiple_threads_at_once() 

Таким образом, каждый поток должен KAVE маркер для выполнения этого метода. Скажите нам, если это поможет!

+0

Нет, я до сих пор не использовал синхронизированное ключевое слово. это шов, что он отлично работает. спасибо! ♥ ♥ ♥ –

+0

Добро пожаловать! –

1

вы должны использовать синхронизацию ... просто синхронизировать метод

public static synchronized void some_method_called_by_multiple_threads() throws java.lang.InterruptedException 

синхронизация просто означает, что один поток может получить доступ к методу в то время. см. документацию по API для получения более подробной информации.

Смежные вопросы