简体   繁体   English

线程同步Java

[英]Thread synchronization Java

I am working on Android App and unable to synchronize View with Hardware. 我正在使用Android App,无法将View与硬件同步。 Let me explain. 让我解释。

1) I mute and unmute microphone of Android based on random values (which are random sleeps) stored in array A, from within run method of Thread 1. 1)我根据线程1的run方法中存储在数组A中的随机值(随机休眠)静音和取消静音Android的麦克风。

2) I draw blue pulses that reflects the mutes of microphone. 2)我画出反映麦克风静音的蓝色脉冲。 This is done by independent View class. 这是由独立的View类完成的。

3)I move a red line across the graph drawn in above view, by calling from within onTick of a countdown timer. 3)我在上面视图中绘制的图形上移动一条红线,通过在倒数计时器的onTick内调用。

I start the two threads one after other, this way: 我一个接一个地启动两个线程,这样:

Thread1.start Thread1.start

counter.start(); counter.start();

How to synchronize both of these, I want to do three things at a time and avoid multiple threads. 如何同步这两个,我想一次做三件事,避免多个线程。 Three things are: Draw the pulses (which is constant) , make the red line move across x axis and touch the blue pulse as soon as the phone is muted, and keep moving every second, the width of pulse reflects duration of delay. 有三个方面:绘制脉冲(恒定),使红线在x轴上移动,一旦手机静音就触摸蓝色脉冲,并且每秒保持移动,脉冲宽度反映延迟的持续时间。 as soon as microphone is about to be unmuted, red line should leave the pulse and move forward. 一旦麦克风即将取消静音,红线应该离开脉冲并向前移动。

Currently, code is doing what I want. 目前,代码正在做我想要的。 but there is no synchroization. 但没有同步。 Either microphone does its job first, or graph moves fast. 麦克风要先完成它的工作,要么图表快速移动。 They are not in Sync. 他们没有同步。

Is there a way to hold a thread, force it to behave as coutdowntimer or sync both of them. 有没有办法保持一个线程,强制它表现为coutdowntimer或同步他们两个。 I cannot embed the red line movement in thread 1 because, it will have to progress across x axis every second. 我不能在线程1中嵌入红线运动,因为它必须每秒在x轴上进行。

It sounds like you are going to need to use a " ReentrantLock " and a " Condition " 听起来你需要使用“ ReentrantLock ”和“ Condition

You can make one thread "wait" for another using the Condition created from a Reentrant lock: 您可以使用从可重入锁创建的条件使一个线程“等待”另一个线程:

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();
  }
}

The line "condition.await()" in threadTwoMethod will cause threadTwoMethod to pause until threadOneMethod calls "condition.singalAll()". threadTwoMethod中的“condition.await()”行将导致threadTwoMethod暂停,直到threadOneMethod调用“condition.singalAll()”。 Before calling signal, or await, on a condition you must own the lock that the condition was created from which is why we have the "lock.lock() / lock.unlock()" calls. 在调用signal或await之前,你必须拥有创建条件的锁,这就是为什么我们有“lock.lock()/ lock.unlock()”调用。

calls to await() should be placed in a while loop because your thread could be randomly woken up, even if the condition on which it is waiting hasn't been signaled. 对await()的调用应放在while循环中,因为你的线程可以被随机唤醒,即使它没有发出等待的条件。 The loop is accomplished in this example by using a boolean flag. 在这个例子中,通过使用布尔标志完成循环。

Remember to lock/unlock in try and finally blocks. 记得在try和finally块中锁定/解锁。 If you throw an exception you will want to make sure you still unlock your lock, which is why we put unlock in a finally block. 如果你抛出异常,你会想确保你仍然解锁你的锁,这就是我们将解锁放在finally块中的原因。

You could also use a LinkedBlockQueue and "take" to accomplish something similar in a less confusing way. 您还可以使用LinkedBlockQueue并“采取”以较少混淆的方式完成类似的操作。 If I had more time I would be more explicit, but I hope this helps. 如果我有更多的时间,我会更明确,但我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM