首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java线程协作与三个线程打印额外数字

Java线程协作与三个线程打印额外数字
EN

Stack Overflow用户
提问于 2022-03-02 19:53:14
回答 1查看 176关注 0票数 0

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

1是打印序列1, 4, 7, 10, ...

  • Thread-2是打印序列2, 5, 8, ...

  • Thread-3是打印序列3, 6, 9, ...

当其他线程轮流打印其序列时,线程应该等待。线程应该相互配合,按顺序从1打印数字到限制(整数,这里限制= 10)。

预期产出

(限值= 10)

代码语言:javascript
复制
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)

代码语言:javascript
复制
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)

代码

代码语言:javascript
复制
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(),分别由线程-1、线程-2和线程-3调用.这些线程使用wait()notifyAll()方法相互协作。

为什么产出总是涉及两个额外的数字,这些数字超过了给定的10的限制,即11和12?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-03 04:38:41

当线程被唤醒(wait->runnable)时,它需要再次判断当前的counter是否小于LIMIT,否则,它将继续打印,直到while (counter <= LIMIT)无法保存为止。(这就是为什么1112也会被打印出来)。

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

代码语言:javascript
复制
    // 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();
        }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71328425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档