我最近开始在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。
任何帮助将不胜感激。
另一种方法是保留两个几何学整数
,如下所示:
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();
}
免责声明:我在回答OP问题的实际对应部分-串行输入和输出的并行处理。更有趣。
>
System.out
。无论我如何构建代码,它前面都会有显式或隐式的队列/争用。Produce
→Stringize
→Output
。字符串化
步骤可以并行完成,前提是有序输出
仍然可以发生。我从快速开始
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();
你需要安排线程之间的交互。线程交互最自然的方式是建立连接线程的阻塞队列。队列可以是独立的对象,或者属于特定的线程。在你的例子中,你需要用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);
}
}
}
创建线程后并开始之前,您需要分配字段name
和Next
。我相信您可以自己编程。此外,第一个线程必须提供初始值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... 我想出了下面的代码,使用两个线程打印,但我无法找出如何从第三个线程在这里打印数字的条件。 如何有效地解决这类问题?