两个线程并行运行:
线程 1:
while(...) {
<-- wait until thread2 is not in update()
doWork();
}
线程 2:
while(...) {
doWork();
<-- wait until thread1 is not in work()
update();
}
我认为上面的示例解释了我尝试做的事情,但我真的不知道如何进行同步。 thread2
的 update()
方法很关键,执行时 thread2
必须等待。
编辑:
到目前为止,感谢您的回答。不止一个运作良好。有人问我想做什么,我想就此做一个简短的更新。
基于currentState
thread2 计算nextState
并交换两者,然后无限重复计算。 thread1 在 gui 中为用户显示“currentState”。
Thread1 不应在当前正在进行交换时显示 currentState
。
就这些。
最佳答案
使用Lock
是最简单的方法。这是一个简单的演示。我们创建两个 Runnable
并启动它们在两个线程下运行。然后我们等待 30 秒,然后打断它们并等待它们完成。
// Lock shared between both threads.
final Lock lock = new ReentrantLock();
// Random numbers.
final Random random = new Random();
public void test() throws InterruptedException {
// Process 1 is a runnable.
Runnable p1 = new Runnable() {
@Override
public void run() {
while (true) {
try {
// Grab the lock.
lock.lock();
// Do my work.
doWork();
} catch (InterruptedException ex) {
System.out.println("P1 Interrupted!");
break;
} finally {
// Release the lock in a `finally` to ensure it can never be left locked.
lock.unlock();
}
}
}
private void doWork() throws InterruptedException {
long wait = random.nextInt(2000);
System.out.println("P1 Working ... " + wait);
// Wait up to 2 seconds.
Thread.sleep(wait);
System.out.println("P1 Work done");
}
};
Runnable p2 = new Runnable() {
@Override
public void run() {
while (true) {
try {
// Do my work.
doWork();
// Grab the lock.
lock.lock();
// Do my update.
update();
} catch (InterruptedException ex) {
System.out.println("P2 Interrupted!");
break;
} finally {
lock.unlock();
}
}
}
private void doWork() throws InterruptedException {
long wait = random.nextInt(2000);
System.out.println("P2 Working ... " + wait);
// Wait up to 2 seconds.
Thread.sleep(wait);
System.out.println("P2 Work done");
}
private void update() throws InterruptedException {
long wait = random.nextInt(2000);
System.out.println("P2 Update ... " + wait);
// Wait up to 2 seconds.
Thread.sleep(wait);
System.out.println("P2 Update done");
}
};
// Create the two threads.
Thread t1 = new Thread(p1);
Thread t2 = new Thread(p2);
// Start them up.
t1.start();
t2.start();
// Wait 30 seconds - with narrative.
for (int i = 0; i < 30; i++) {
Thread.sleep(1000);
System.out.println("Tick");
}
// Stop them.
t1.interrupt();
t2.interrupt();
// Wait for them to stop.
t1.join();
t2.join();
}
运行此程序应该可以证明您的设计存在问题之一。请注意,P2 Update
很少被调用。这是因为 P1
花费很少的时间来释放锁,因此使另一个线程处于饥饿状态。看看在 p1
中它将如何 lock.unlock()
然后几乎立即再次执行 lock.lock()
因为它再次开始循环.
关于java - 同步两个循环的 Java 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31406174/