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

按特定顺序打印从1到10的整数,仅使用5个线程。[重复]

井誉
2023-03-14

我最近开始在Java中使用多线程

我有一个问题,解决了一个问题,我只有5个线程,范围从T1、T2、... T5。

任务是按以下顺序打印从1到10的数字。

T1 -> 1
T2 -> 2
T3 -> 3
T4 -> 4
T5 -> 5
T1 -> 6
T2 -> 7
T3 -> 8
T4 -> 9
T5 -> 10

我试着用这段代码解决它。

public static void main(String[] args) throws InterruptedException {
    Counter counter = new Counter();
    Thread[] tArray = new Thread[] { new Thread(counter, "T1"), new Thread(counter, "T2"),
            new Thread(counter, "T3"), new Thread(counter, "T4"), new Thread(counter, "T5") };
    for (int i = 0; i < 10; i++) {
        if (i < 5) {
            tArray[i].start();
            tArray[i].join();
        } else {
            tArray[i - 5] = new Thread(counter, "T" + ((i - 5) + 1)); //Instantiating new Thread which is not allowed.
            tArray[i - 5].start();
            tArray[i - 5].join();
        }
    }
}

public class Counter implements Runnable {

    private int count = 0;

    @Override
    public synchronized void run() {
       System.out.println(Thread.currentThread().getName() + " -> " + ++count);
    }

}

但是由于只允许5个线程,我的解决方案没有被接受,因为我也在< code>for循环的< code>else块中实例化了< code>new Thread。

任何帮助将不胜感激。

共有3个答案

金高轩
2023-03-14

另一种方法是保留两个几何学整数,如下所示:

static class MyRunnable implements Runnable {

    private final AtomicInteger index;
    private final AtomicInteger ai;
    private final int[] array;
    private final int current;
    private final int next;

    public MyRunnable(AtomicInteger index, AtomicInteger ai, int[] array, int current, int next) {
        this.index = index;
        this.ai = ai;
        this.array = array;
        this.current = current;
        this.next = next;
    }

    @Override
    public void run() {
        for (;;) {
            if (index.get() == array.length) {
                break;
            }
            if (ai.get() == current) {
                System.out.println(Thread.currentThread().getName() + " " + array[index.getAndIncrement()]);
                ai.compareAndSet(current, next);
            }
        }
    }
}

并且使用将是:

public static void main(String[] args) {

    int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    AtomicInteger ai = new AtomicInteger(1);
    AtomicInteger index = new AtomicInteger(0);

    Thread t1 = new Thread(new MyRunnable(index, ai, array, 1, 2), "T1");
    Thread t2 = new Thread(new MyRunnable(index, ai, array, 2, 3), "T2");
    Thread t3 = new Thread(new MyRunnable(index, ai, array, 3, 4), "T3");
    Thread t4 = new Thread(new MyRunnable(index, ai, array, 4, 5), "T4");
    Thread t5 = new Thread(new MyRunnable(index, ai, array, 5, 1), "T5");

    t1.start();
    t2.start();
    t3.start();
    t4.start();
    t5.start();

}
隗星驰
2023-03-14

免责声明:我在回答OP问题的实际对应部分-串行输入和输出的并行处理。更有趣。

>

  • 我有一个串行资源 - System.out。无论我如何构建代码,它前面都会有显式或隐式的队列/争用。
  • 处理争用的最佳方法是通过显式排队(可以观察、量化和寻址,这与使用互斥锁或同步块上的隐式队列相反)。
  • 我的是一个3步管道:ProduceStringizeOutput
  • 字符串化步骤可以并行完成,前提是有序输出仍然可以发生。
  • 我从快速开始

    final Executor inputWorker = newSingleThreadExecutor();
    final Executor processingPool = newFixedThreadPool(3);
    final Executor outputWorker = newSingleThreadExecutor();
    
    final int[] counter = {-1}; // this emulates a non-thread-safe information source
    CompletableFuture<Void> future = completedFuture(null);
    for (int i = 0; i < 10; ++i) {
        future = future // chaining of futures is essential for serializing subsequent iterations
                .thenApplyAsync(unused -> ++counter[0], inputWorker)
                .thenApplyAsync(Objects::toString, processingPool)
                .thenAcceptAsync(System.out::println, outputWorker);
    }
    future.join();
    

    PS - 为了完整性,人们可能希望步骤#5略有不同,首先创建整个计算计划,然后触发它:

    final Executor producer = newSingleThreadExecutor();
    final Executor stringizer = newFixedThreadPool(3);
    final Executor printer = newSingleThreadExecutor();
    
    final int[] counter = {-1}; // this emulates a non-thread-safe information source
    
    System.out.println("creating schedule...");
    // first schedule the whole amount of work and block the execution on a single "trigger" future
    final CompletableFuture<Void> trigger = new CompletableFuture<>();
    CompletableFuture<Void> future = trigger;
    for (int i = 0; i < 10; ++i) {
        future = future
                .thenApplyAsync(unused -> ++counter[0], producer)
                .thenApplyAsync(Objects::toString, stringizer)
                .thenAcceptAsync(System.out::println, printer);
    }
    
    // then pull the trigger
    System.out.println("pulling the trigger...");
    trigger.complete(null);
    future.join();
    

  • 暴阳州
    2023-03-14

    你需要安排线程之间的交互。线程交互最自然的方式是建立连接线程的阻塞队列。队列可以是独立的对象,或者属于特定的线程。在你的例子中,你需要用5根线围成一个圈。

    class CountPrinter extends Thread {
       String name;
       ArrayBlockingQueue<Integer> inp = new ArrayBlockingQueue<>();
       CountPrinter next;
    
       public void run() {
          for (;;)
             int n = inp.take();
             if (n == 11) {// only 10 numbers must be printed
                next.inp.put(11);
                return;
             }
             System.out.println(name+"->"+n);
             next.inp.put(n+1);
          }
       }
    }
    

    创建线程后并开始之前,您需要分配字段nameNext。我相信您可以自己编程。此外,第一个线程必须提供初始值1

     类似资料:
    • 我是多线程的新手,我有一个问题,要在Java中使用10个线程打印1到100,并使用以下约束。 > 线程 应打印: 1, 11, 21, 31, ...91 < code>t2应打印: 2, 12, 22, 32, ... 92 同样地 < code>t10应打印: 10, 20, 30, ... 100 最终输出应为: 1 2 3 ..100 我已经尝试过了,但它在所有10个线程中都抛出了以下异常

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

    • 我试图创建一个实现,其中多个线程打印序列的备用值。这里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,而我希望保持顺序,因为正确的线程可以打印这些

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

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

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