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

3个线程按顺序打印备用值

刘向阳
2023-03-14

我试图创建一个实现,其中多个线程打印序列的备用值。这里thread1将打印1,4,7 thread2将打印2,5,8 thread3将打印3,6,9。我用的是原子整数和模函数

下面的实现可以很好地工作,第一个线程打印1,4,7,第二个线程打印2,5,8,第三个线程打印3,6,9,但问题是没有保持顺序,即输出可能类似于1,3,2,4,5,7,8,6,9,而我希望保持顺序,因为正确的线程可以打印这些值。一个条件是我不想使用同步。[仅用于学习目的]

import java.util.concurrent.atomic.AtomicInteger;

public class ThreeThreadsOrderedLockLess {

    AtomicInteger sharedOutput = new AtomicInteger(0);

    public static void main(String args[]) {



        ThreeThreadsOrderedLockLess t = new ThreeThreadsOrderedLockLess();



        ThreadTasks t1 = t.new ThreadTasks(0);
        ThreadTasks t2 = t.new ThreadTasks(1);
        ThreadTasks t3 = t.new ThreadTasks(2);

        Thread ts1 = new Thread(t1);
        Thread ts2 = new Thread(t2);
        Thread ts3 = new Thread(t3);
        ts1.start();
        ts2.start();
        ts3.start();

    }

    private class ThreadTasks implements Runnable {

        private final int threadPosition;


        public ThreadTasks(int threadPosition) {
            super();

            this.threadPosition = threadPosition;
        }

        @Override
        public void run() {

            while (sharedOutput.get() < 9) {

                if (sharedOutput.get() % 3 == this.threadPosition) {

                    System.out.println("Printing output for Thread: "
                            + this.threadPosition + "  "
                            + sharedOutput.incrementAndGet());
                }
            }

        }
    }

}

共有3个答案

南门洋
2023-03-14

这是因为每个线程的时间片是由操作系统决定的。所以线程x有可能增加共享数,但是在打印之前,时间片被传递给下一个线程y,它现在读取共享数并在增加后打印它(假设线程y比线程x有更多的时间来增加和打印共享数)。

杨学真
2023-03-14

下面的代码片段将按顺序打印数字,所有线程将在任务完成后优雅地终止。使用AtomicInteger,它对打印数字是线程安全的,同样的逻辑可以应用于打印任意线程数的数字。

 
    import java.util.concurrent.atomic.AtomicInteger;

    public class PrintNumSequence
    {
        public static void main(String[] args)
        {
          AtomicInteger atomicInteger = new AtomicInteger(0);
          new NumPrinter(atomicInteger, 0).start();// thread0
          new NumPrinter(atomicInteger, 1).start();// thread1
          new NumPrinter(atomicInteger, 2).start();// thread2

        }
    }

    class NumPrinter extends Thread
    {

        private AtomicInteger   atomicInteger;
        private int             threadNum;

       public NumPrinter(AtomicInteger atomicInteger, int threadNum)
       {
        this.atomicInteger = atomicInteger;
        this.threadNum = threadNum;
       }

       @Override
       public void run()
       {
        int num = atomicInteger.intValue();
        do
        {
            synchronized (atomicInteger)
            {
                num = atomicInteger.intValue();
                // If number is 9 then stop.
                if (num > 9)
                {
                    atomicInteger.notifyAll();
                    break;
                }
                // 3 is number of threads
                if ((num % 3) == threadNum)
                {
                    System.out.println("Thread-" + threadNum + " -->" + num);
                    num = atomicInteger.incrementAndGet();

                }
                atomicInteger.notifyAll();
                try
                {
                    atomicInteger.wait();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
         } while (true);
       }
     }
丌官浩旷
2023-03-14

您应该先打印,然后递增:

int value = sharedOutput.get() + 1;
System.out.println("Printing output for Thread: "
                        + this.threadPosition + "  "
                        + value);
sharedOutput.incrementAndGet();

也就是说,所有线程都忙于循环,这将导致100%的CPU使用率。你应该同步线程。

 类似资料:
  • 这个问题是在电子艺术采访中提出的。 有三条线。第一个线程打印1到10个数字。第二个线程打印从11到20的数字。第三条线从21到30。现在这三个线程都在运行。然而,数字是按不规则的顺序打印的,如1、11、2、21、12等。 如果我想让数字按排序顺序打印,比如1,2。。。我该怎么处理这些线呢?

  • 采访中问 有三条线。第一条线打印100到199个数字。第二个线程打印200到299之间的数字。第三条线从300到399。执行的顺序是

  • 问题内容: 我有3个线程第一打印A第二打印B第三打印C 我想按顺序打印ABCABCABC,依此类推..... 因此,我在下面编写了程序,但无法实现相同的目的。我知道一个问题,当时状态为1时,例如B1和C1线程正在等待,而当我做notifyAll()时,两个等待线程都被唤醒,并且取决于CPU分配,它可能会打印B或C。 在这种情况下,我只希望在A之后打印B。 我需要做什么修改。 问题答案: 将那些IF

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

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

  • 我最近开始在Java中使用多线程 我有一个问题,解决了一个问题,我只有5个线程,范围从T1、T2、... T5。 任务是按以下顺序打印从1到10的数字。 我试着用这段代码解决它。 但是由于只允许5个线程,我的解决方案没有被接受,因为我也在< code>for循环的< code>else块中实例化了< code>new Thread。 任何帮助将不胜感激。