我必须从用户那里获取线程数和序列中的最大数量作为输入,并且我必须使用创建的线程数打印从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
答案 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变量需要是静态的,所以它将是你所有线程可用的相同实例。