2010-08-02 7 views
3

Я работаю над Android-приложением и не могу синхронизировать View with Hardware. Позвольте мне объяснить.Синхронизация потоков Java

1) Я Отключение и включение микрофона из Android на основе случайных значений (которые являются случайными) спит, хранящихся в массиве А, в рамках метода выполнения резьбы 1.

2) Обращаю голубые импульсы, которые отражают приглушения микрофона. Это делается независимым классом View.

3) Я перемещаю красную линию по графику, нарисованному в виде сверху, путем вызова внутри onTick таймера обратного отсчета.

я начала два потока один за другим, таким образом:

Thread1.start

counter.start();

Как синхронизировать оба из них, я хочу делать три вещи одновременно и избегать нескольких потоков. Три вещи: Нарисуйте импульсы (которые постоянны), сделайте красную линию движением по оси x и коснитесь синего импульса, как только телефон отключится, и продолжайте движение каждую секунду, ширина импульса отражает длительность задержки. как только микрофон будет отключен, красная линия должна оставить импульс и двигаться вперед.

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

Есть ли способ удержать нить, заставить ее вести себя как coutdowntimer или синхронизировать их оба. Я не могу встроить движение красной линии в поток 1, потому что он должен будет проходить через ось x каждую секунду.

+0

Нужно уточнить: есть ли Thread1, спать, бодрствовать, заглушать, спать, бодрствовать, отключать, спать, бодрствовать, заглушать, спать ... и т. Д.? Красная линия должна начать рисовать, как только появится синий импульс, и пройдите скорость, необходимую для того, чтобы оставить импульс в то самое время, когда микрофон отключен? –

+0

Резьба1 недействительной Run() { для (в 10 раз) { audioService.setMicrophoneMute (ложь); thread.sleep; audioService.setMicrophoneMute (true); thread.sleep; } } –

ответ

13

Это звучит, как вы будете нуждаться, чтобы использовать «ReentrantLock» и «Condition»

Вы можете сделать один поток «ждать» за другой, используя условие, созданное из замка реентрантного:

private ReentrantLock lock = new ReentrantLock(); 
private Condition condition = lock.newCondition(); 
private boolean someFlag = false; 
public void threadOneMethod() { 
    lock.lock(); 
    try { 
    someFlag = true; 
    condition.signalAll(); 
    } finally { 
    lock.unlock(); 
    } 
} 
public void threadTwoMethod() { 
    lock.lock(); 
    try { 
    while (someFlag == false) { 
     condition.await(); 
    } 

    System.out.println("Did some stuff"); 
    someFlag = false; 
    } finally { 
    lock.unlock(); 
    } 
} 

Строка «condition.await()» в threadTwoMethod заставит threadTwoMethod приостанавливаться до тех пор, пока threadOneMethod не вызовет «condition.singalAll()». Перед вызовом сигнала или ожиданием, при условии, вы должны владеть блокировкой, что условие было создано, поэтому мы имеем вызовы «lock.lock()/lock.unlock()».

Звонки на ожидание() должны быть помещены в цикл while, потому что ваш поток может быть случайно проснулся, даже если условие, на котором оно ожидает, не было сигнализировано. Цикл выполняется в этом примере с помощью булевого флага.

Не забывайте блокировать/разблокировать в попытке и, наконец, блокировать. Если вы выбросите исключение, вы захотите убедиться, что вы все еще разблокируете блокировку, поэтому мы кладем разблокировку в блок finally.

Вы также можете использовать LinkedBlockQueue и «взять», чтобы добиться чего-то подобного в менее запутанном виде. Если бы у меня было больше времени, я бы стал более явным, но я надеюсь, что это поможет.

+0

Еще одна вещь. Мне нравится параллельный аспект вашего кода, последнее, что я могу прокомментировать, - это то, что флаг не должен быть изменчивым здесь, потому что он защищен соответствием «блокировкой». Будучи ничтожным выбором, я знаю, но его всегда хорошо знать :) –

+0

ах, да, вы правы. Не думал: o –

+0

Thankk you very much –

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