使用多个线程显示序列

时间:2016-10-06 07:35:25

标签: java multithreading

我必须从用户那里获取线程数和序列中的最大数量作为输入,并且我必须使用创建的线程数打印从0到最大数字的序列,每个线程应该至少打印1个数字而不是允许重复相同的数字。

我的代码是为每个创建的线程打印序列,因此重复序列中的数字。请告诉我如何让所有线程一起打印seqeunce而不是单独打印,以便我可以输出像

max sequence-4
max threads-3
Thread 1-0
Thread 2-1
Thread 3-2
Thread 1-3

用于打印序列的变量应该是静态的吗?

这是我的代码 -

package com.demo;

import java.util.Scanner;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class SequencePrinter {

public static void main(String[] args) {

    System.out.println("Enter the no.Of threads");
    Scanner sn = new Scanner(System.in);
    int n = sn.nextInt();// No. of Threads

    Worker t1[] = new Worker[n];
    System.out.println("Enter the max no.");
    Scanner sc = new Scanner(System.in);
    int r = sc.nextInt();// MAX no.

    for (int i = 0; i < n; i++) {
        t1[i] = new Worker();

    }

    for (int i = 0; i < n - 1; i++) {
        t1[i].setNext(t1[i + 1]);
    }

    // Create the workers
    // Worker w1 = new Worker();
    // Worker w2 = new Worker();
    // Worker w3 = new Worker();

    // chain them in a round robin fashion
    // w1.setNext(w2);
    // w2.setNext(w3);
    // w3.setNext(w1);

    // for (int i = 0; i < t1.length; i++) {
    //
    // Thread t[i] = (Thread) new Thread(t1[i], "Thread-" + "i" + "-");
    //
    // }

    // Create named threads for the workers
    // Thread t1 = new Thread(w1, "Thread-1 - ");
    // Thread t2 = new Thread(w2, "Thread-2 - ");
    // Thread t3 = new Thread(w3, "Thread-3 - ");

    // start the threads

    for (int i = 0; i < t1.length; i++) {
        t1[i].start();

    }

    // t1.start();
    // t2.start();
    // t3.start();

    // Seed the first worker
    t1[0].accept(0);
    // t1[1].accept(1);
    // try
    // {
    // t1[0].join();
    // }
    // catch(Exception e)
    // {
    // System.out.println("exception");
    // }
    for (int i = 0; i < t1.length; i++) {
        t1[i].setVar(r);

    }

}

}

class Worker extends Thread {

int r = 0;
int prnt = 0;
BlockingQueue<Integer> q = new LinkedBlockingQueue<Integer>();
Worker next = null; // next worker in the chain

public void setNext(Worker t) {
    this.next = t;
}

public void accept(int i) {
    q.add(i);
}

@Override
public String toString() {
    // TODO Auto-generated method stub
    return super.toString();
}

public void setVar(int i) {
    r = i;// The Max no.to print
}

int[] ij = new int[r];

@Override

public synchronized void run() {

    try {

        int i = q.take(); // blocks till it receives a number

        while (r != prnt) {

            System.out.println(Thread.currentThread().getName() + ":" + prnt);

            Thread.sleep(1000); // delay to slow the printing

            if (next != null) {

                next.accept(i + 1); // pass the next number to the next
            }
            // if(prnt==0|| prnt==1)
            prnt = prnt + 1;

        }

    } catch (InterruptedException e) {
        System.err.println(Thread.currentThread().getName() + " interrrupted.");
    }

}
}


the code prints folllowing output

Enter the no.Of threads
2
Enter the max no.
4
Thread-0:0
Thread-0:1
Thread-1:0
Thread-1:1
Thread-0:2
Thread-0:3
Thread-1:2
Thread-1:3

4 个答案:

答案 0 :(得分:1)

使用具有实际名称的变量和方法,代码更具可读性。

import java.util.Scanner;

class SequencePrinter
{
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);

        System.out.print("number of threads: ");
        final int numberOfThreads = scanner.nextInt();

        System.out.print("maximum number to print: ");
        final int maximumNumber = scanner.nextInt();

        scanner.close();

        for (int index = 0; index < numberOfThreads; ++index)
        {
            final int workerIndex = index;

            Thread worker = new Thread(new Runnable()
            {
                public void run()
                {
                    for (int number = workerIndex; number <= maximumNumber; number += numberOfThreads)
                    {
                        print(workerIndex, number);
                    }
                }
            });

            worker.start();
        }
    }

    synchronized
    private static void print(int thread, int number)
    {
        System.out.println("thread " + thread + ", number " + number);
    }
}

答案 1 :(得分:0)

使用Java8和Executor API功能怎么样?

import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;

public class Use {
    public static void main(String[] args) {
        try (Scanner scanner = new Scanner(System.in)) {
            System.out.print("Number of threads: ");
            int numberOfThreads = scanner.nextInt();

            System.out.print("Maximum number to print: ");
            int maximumNumber = scanner.nextInt();

            ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);
            Integer sequence = new Integer(0);
            IntStream.range(0, maximumNumber)
                        .forEach(i -> pool.submit(() -> {
                            synchronized (sequence) {
                                System.out.println(Thread.currentThread().getName() + ": " + sequence++);
                            }
                        }));

            pool.shutdown();
        }
    }
}

注意:正如@starikoff所说,此代码不保证OP的要求每个线程至少应该打印1个数字

答案 2 :(得分:0)

因为提到了使用AtomicInteger的想法:它没有太大变化,并且肯定不会使输出顺序排序:

import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;

class SequencePrinter
{
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);

        System.out.print("number of threads: ");
        final int numberOfThreads = scanner.nextInt();

        System.out.print("maximum number to print: ");
        final int maximumNumber = scanner.nextInt();

        scanner.close();

        final AtomicInteger currentNumber = new AtomicInteger(0);

        for (int index = 0; index < numberOfThreads; ++index)
        {
            final int workerIndex = index;

            Thread worker = new Thread(new Runnable()
            {
                public void run()
                {
                    while (true)
                    {
                        int number = currentNumber.getAndIncrement();

                        if (number <= maximumNumber)
                        {
                            print(workerIndex, number);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            });

            worker.start();
        }
    }

    synchronized
    private static void print(int thread, int number)
    {
        System.out.println("thread " + thread + ", number " + number);
    }
}

会话:

number of threads: 3
maximum number to print: 11
thread 0, number 0
thread 2, number 2
thread 2, number 4
thread 2, number 5
thread 2, number 6
thread 2, number 7
thread 2, number 8
thread 2, number 9
thread 2, number 10
thread 2, number 11
thread 1, number 1
thread 0, number 3

原因是AtomicInteger不同步输出。这只是确保每个数字只打印一次的另一种方法。在另一个例子中,这是通过数学技巧实现的:)

这不是解决方案,顺便说一句,因为不能保证每个线程最终都会打印任何东西。一个线程最终可能会打印所有数字。

答案 3 :(得分:-1)

请查看课程AtomicInteger。它完全符合您的目的,并使您的代码更简单。您不必担心检查重复。您需要的所有线程都是获取一个值并检查它是否小于或等于最大值,如果是,则打印它。否则只是终止线程。是的,你的AtomicInteger变量需要是静态的,所以它将是你所有线程可用的相同实例。