java - 同步两个循环的 Java 线程

标签 java multithreading

两个线程并行运行:

线程 1:

while(...) {
  <-- wait until thread2 is not in update()
  doWork();
}

线程 2:

while(...) {
  doWork();
  <-- wait until thread1 is not in work()
  update();
}

我认为上面的示例解释了我尝试做的事情,但我真的不知道如何进行同步。 thread2update() 方法很关键,执行时 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/

相关文章:

java - 如何忽略单元测试中的某些字段,Hibernate

java - 从 Pane 中删除元素时,阻止 GridBagLayout 调整列/行的大小?

java - 如何确保传递给方法的集契约(Contract)步?

c++ - 无法打开包含文件 'thread'

java - 退出线程时如何执行代码

java - Android for 循环中的 “Only the original thread that created a view hierarchy can touch its views.” 错误

java - 如何通过UNIX mac终端调试maven项目?

java - 如何在java/jsp或javascript中读取扫描的pdf文件的内容

java - 是否可以在注释处理之前向类注入(inject)额外的注释?

multithreading - 在原子上调用 `into_inner()` 是否考虑了所有宽松的写入?