java - 使用两个线程一次打印一个字母和数字

标签 java multithreading concurrency thread-safety

我正在研究以下面试问题,我需要使用两个线程打印字母和数字。一个打印字母 (a,b,c...z),另一个打印数字 (1,2,3...26)。现在我必须以这样的方式实现它,输出应该是:

a
1
b
2
...
...
z
26

所以我想出了下面的代码一,没有同步,但由于某种原因,它没有打印最后一个字母,即z

class Output {
  private static final int MAX = 26;
  private static int count = 1;
  private static final Queue<Character> queue = new LinkedList<>(Arrays.asList(new Character[] {
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
      's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}));
  private boolean isAlphabet = true;

  public void printAlphabet() {
    while (true) {
      if (count > MAX)
        break;
      if (!isAlphabet) {
        System.err.println(Thread.currentThread().getName() + " : " + queue.remove());
        isAlphabet = true;
      }
    }
  }

  public void printNumber() {
    while (true) {
      if (count > MAX)
        break;
      if (isAlphabet) {
        System.err.println(Thread.currentThread().getName() + " : " + count++);
        isAlphabet = false;
      }
    }
  }
}


public class PrintAlphabetNumber {
  public static void main(String[] args) {
    Output p = new Output();
    Thread t1 = new Thread(() -> p.printAlphabet());
    t1.setName("Alphabet");
    Thread t2 = new Thread(() -> p.printNumber());
    t2.setName("Number");

    t1.start();
    t2.start();
  }
}

我上面的代码有问题吗?另外从同步的角度来看,它看起来好不好?

最佳答案

for some reason it is not printing last alphabet which is z

count > MAX 时,您将中止,这在最后一个数字之后为真。

在最后一个数字之后,您应该打印最后一个字母,但现在 count > MAX 所以它已经停止了。

from synchronization perspective, does it look good or not?

不,这看起来不太好。

您正在使用自旋锁。这是非常低效的,因为两个循环都持续使用 100% CPU,无论它们是否有工作要做。也不保证它可以与非 volatile 锁变量一起使用。

经典的 Java 解决方案将使用 wait()/notify()

关于java - 使用两个线程一次打印一个字母和数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52786332/

相关文章:

java - 矩阵加法java

java - 小程序计算和监听器问题和外观

python - Python 中的线程需要更长的时间而不是使其更快?

java - 在 Web 应用程序中使用 Java 和 JSON 文件设计建议

Java 使用 GridBagLayout 限制 JPanel 的宽度

java - Java 中的垃圾收集

python - Twisted:为什么将延迟回调传递给延迟线程会使线程突然阻塞?

c++ - 我想重新运行一个线程

windows - 网络共享文件夹上的 GIT 存储库中的并发性

python - 试图理解 Python 的 Concurrent.Futures 模块