2013-11-11 4 views
0

Я использую Bluetooth на Android; Короче говоря, я только хочу открыть новый поток для получения, если сокет в настоящее время не подключен - Я тестирую это с помощью логического.Java Thread - это правильное использование синхронизации

Итак:

class Main { 

    protected boolean mConnected; 

    public void startClientConnection() { 
     ClientRunnable thread = new ClientRunnable() { 
     @Override public void manageSocket(BluetoothSocket pSocket) { 
      synchronized (this) { 
       if (!mConnected) openReadingThread(pSocket); 
      } // end synchronized() 
     } // end manageSocket() 
     }; // end ClientRunnable 
    } // end startClientConnection() 

} // End CLASS 

Отредактировано: По сути, то, что мне нужно знать, потому что Runnable будет работать в отдельном потоке, но переменная mConnected будет изменен только в основной Thread, нужно ли его синхронизировать.

+0

1. Возможно ли, чтобы в течение двух этих потоков выполнялось одно и то же время? 2. Важен ли только один поток внутри этого метода за раз? – Cruncher

+0

@Cruncher Да, две отдельные Threads используют этот метод для запуска новой Thread, которая открывает Thread для чтения ввода из Stream. И да, Thread для чтения из Stream нужно только вызывать один раз. Кроме того, спасибо за переделку коммутатора. –

ответ

1

В этом случае каждая создаваемая вами нить имеет свой собственный замок (сам объект) , вы должны использовать что-то статическое (например, класс) для блокировки.

+0

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

+0

нет. Я имею в виду Main.class как блокировку. не 'this' –

1

Простой ответ: mConnected должен быть доступен только в синхронизированном блоке. Код, который вы показываете, хорош, но код, в котором вы изменяете значение, также должен быть в блоке синхронизации. Причина этого в том, что otherwize Java не обязана позволять одному потоку видеть изменения, внесенные другим. В этом случае вам не нужно нужны синхронизирующие блоки для синхронизации всего, просто чтобы заставить каждый поток видеть изменения другого.

Менее простое: это почти хороший пример для создания mConnected volatile. Затем вы можете пропустить синхронизированный блок. Но тогда можно было бы получить два потока в openReadingThread одновременно.

Так держать синхронизирующий блок в вашем примере (который больше для openReadingThread чем для mConnected), и либо использовать другой, когда вы устанавливаете mConnected или сделать mConnected неустойчивыми. Неустойчивые поля дороги, но тогда есть блоки синхронизации, особенно когда вам не нужно синхронизировать, но только сделать поле видимым в потоках. Я бы сказал, если изменений немного, и вы переходите через код выше многого, пропустите volatile и используйте второй блок синхронизации. Но если вы сильно измените значение, перейдите с измененным mConnected и только одним блоком синхронизации (тот, который в вашем примере, который теперь нужен только для метода, а не для mConnected).

Addtional: Я уже собирался рассказать Филиппу Сандеру, что он ошибался в отношении этого «этого», но, на первый взгляд, это не так; он нуждается в исправлении.

+0

Спасибо. Это говорит мне все, что мне нужно знать! Threading - сложная проблема, поэтому я не хотел ошибаться. –

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