当前位置: 首页 > 知识库问答 >
问题:

具有三个线程的Java线程协作打印额外的数字

钮博裕
2023-03-14

我试图通过三个线程打印三个AP序列(增量为3),如下所示:

  • 线程-1正在打印序列1、4、7、10、
  • 线程2正在打印序列2、5、8、…
  • 线程-3正在打印序列3、6、9、…

当任何其他线程轮流打印其序列的数字时,线程应该等待。线程应该相互合作,从1到LIMIT(一个整数;这里LIMIT=10)依次打印数字。

(对于极限 = 10)

1 (printed by Thread-1)
2 (printed by Thread-2)
3 (printed by Thread-3)
4 (printed by Thread-1)
5 (printed by Thread-2)
6 (printed by Thread-3)
7 (printed by Thread-1)
8 (printed by Thread-2)
9 (printed by Thread-3)
10 (printed by Thread-1)

(对于极限 = 10)

1 (printed by Thread-1)
2 (printed by Thread-2)
3 (printed by Thread-3)
4 (printed by Thread-1)
5 (printed by Thread-2)
6 (printed by Thread-3)
7 (printed by Thread-1)
8 (printed by Thread-2)
9 (printed by Thread-3)
10 (printed by Thread-1)
11 (printed by Thread-2)
12 (printed by Thread-3)
class PrintingSequences {
    private static final int LIMIT = 10;
    int counter = 1;
    boolean isPrinting = false;

    // prints 1, 4, 7, 10, ...
    synchronized void printAPStartingFrom1() {
        while (counter <= LIMIT) {
            while (isPrinting || counter % 3 != 1) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    System.out.println(e);
                    Thread.currentThread().interrupt();
                }
            }
            isPrinting = true;
            System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
            isPrinting = false;
            notifyAll();
        }
    }

    // prints 2, 5, 8, 11, ...
    synchronized void printAPStartingFrom2() {
        while (counter <= LIMIT) {
            while (isPrinting || counter % 3 != 2) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    System.out.println(e);
                    Thread.currentThread().interrupt();
                }
            }
            isPrinting = true;
            System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
            isPrinting = false;
            notifyAll();
        }
    }

    // prints 3, 6, 9, 12, ...
    synchronized void printAPStartingFrom3() {
        while (counter <= LIMIT) {
            while (isPrinting || counter % 3 != 0) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    System.out.println(e);
                    Thread.currentThread().interrupt();
                }
            }
            isPrinting = true;
            System.out.println(counter++ + " (printed by " + Thread.currentThread().getName() + ")");
            isPrinting = false;
            notifyAll();
        }
    }
}

public class TripleThreadCommunication {
    public static void main(String[] args) {
        PrintingSequences naturalNumbers = new PrintingSequences();

        new Thread("Thread-1") {
            @Override
            public void run() {
                naturalNumbers.printAPStartingFrom1();
            }
        }.start();

        new Thread("Thread-2") {
            @Override
            public void run() {
                naturalNumbers.printAPStartingFrom2();
            }
        }.start();

        new Thread("Thread-3") {
            @Override
            public void run() {
                naturalNumbers.printAPStartingFrom3();
            }
        }.start();
    }
}

该程序有三种不同的同步方法:printAPStartingFrom1()printAPStartingFrom2()printAPStartingFrom3(),分别由Thread-1、Thread-2和Thread-3调用。线程使用waiting()elle fyAll()方法相互配合。

为甚么结果总是涉及两个额外数字,即11和12,而这两个数字又超出了既定的10个上限?

共有1个答案

田镜
2023-03-14

当线程被唤醒时(< code>wait)

我建议您提前确定每个线程将循环多少次(这将使代码更简单):

    // thread1
    // prints 1, 4, 7, 10, ...
    synchronized void printAPStartingFrom1() {
        int count = LIMIT % 3 == 0 ? LIMIT / 3 : LIMIT / 3 + 1;
        for (int i = 0; i < count; i++) {
            while (counter % 3 != 1) {
                wait();
            }
            printAndAddCounter();
            notifyAll();
        }
    }
    // thread2
    // prints 2, 5, 8, 11, ...
    synchronized void printAPStartingFrom1() {
        int count = (LIMIT - 1) % 3 == 0 ? LIMIT / 3 : LIMIT / 3 + 1;
        for (int i = 0; i < count; i++) {
            while (counter % 3 != 2) {
                wait();
            }
            printAndAddCounter();
            notifyAll();
        }
    }
    // thread3
    // prints 3, 6, 9, 12, ...
    synchronized void printAPStartingFrom1() {
        int count = LIMIT / 3;
        for (int i = 0; i < count; i++) {
            while (counter % 3 != 0) {
                wait();
            }
            printAndAddCounter();
            notifyAll();
        }
    }
 类似资料:
  • 问题内容: 我正在尝试同步三个线程以打印012012012012…。但是它不能正常工作。每个线程都分配有一个编号,当它从主线程接收到信号时将打印该编号。以下程序有问题,我无法捕获。 问题答案: 您需要更多的协调。该notify调用不会立即唤醒线程并强制其继续执行。相反,您可以考虑notify将电子邮件发送给线程以使其可以继续进行。想象一下,如果您想让3个朋友按顺序给您打电话。您向朋友1发送了一封电

  • 问题内容: 我正在尝试使用2个不同的线程交替打印奇数和偶数。我能够使用等待,通知和同步块来实现它,但是现在我想评估是否可以不使用等待,通知和同步来实现它。 以下是我拥有的代码,但无法正常工作: } 有任何想法吗? 根据Bruno的建议,我创建了另一个版本,该版本似乎效果更好: 问题答案: 代码未正确同步,这就是问题所在。 您的代码中允许以下执行顺序: 第一个线程看到,将其设置为并进入块。 第二个线

  • 我正在回答以下面试问题: 一个进程有三个线程。第一个线程打印1 1 1...,第二个打印2 2 2...,第三个打印3 3 3...无休止。你如何安排这三个线程以打印1 2 3 1 2 3... 我想出了下面的代码,使用两个线程打印,但我无法找出如何从第三个线程在这里打印数字的条件。 如何有效地解决这类问题?

  • 有两个线程,一个是打印偶数,另一个是打印奇数。在下面自定义锁的帮助下,我想按顺序打印数字。问题出在打印一些数字后(显示的数字顺序正确。)线程越来越死机。我花了一个多小时还是找不到问题,对我来说一切都很好。

  • 问题内容: 使用线程进行奇数打印,创建一个线程类,两个线程实例。 一个将打印奇数,而另一个将打印偶数。 我做了以下编码。但这涉及到死锁状态。有人可以解释一下原因吗? 输出: 奇数1偶数2 然后陷入僵局!!!!!! 谢谢你的帮助。 问题答案: 您正在等待并通知其他对象( 监视器 )。 这个想法是,你在做和做的时候可以打电话等待一个人做。 将您的方法更改为类似 和方法类似。 然后为提供一个对象: 输出

  • #include <stdio.h> #include <pthread.h> #include <unistd.h> int a = 0; void *thread1_func(void *p_arg) { while (1) { a++; sleep(10); } } int m