gpt4 book ai didi

java - 同步三个线程

转载 作者:搜寻专家 更新时间:2023-10-31 20:11:17 25 4
gpt4 key购买 nike

在面试中被问到这个问题,试图解决它......但没有成功。我想到了使用 CyclicBarrier

有三个线程 T1 打印 1,4,7... T2 打印 2,5,8... 和 T3 打印 3,6,9...。你如何同步这三个打印序列 1,2,3,4,5,6,7,8,9....

我尝试编写并运行以下代码

public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cBarrier = new CyclicBarrier(3);
new Thread(new ThreadOne(cBarrier,1,10,"One")).start();
new Thread(new ThreadOne(cBarrier,2,10,"Two")).start();
new Thread(new ThreadOne(cBarrier,3,10,"Three")).start();
}
}

class ThreadOne implements Runnable {
private CyclicBarrier cb;
private String name;
private int startCounter;
private int numOfPrints;

public ThreadOne(CyclicBarrier cb, int startCounter,int numOfPrints,String name) {
this.cb = cb;
this.startCounter=startCounter;
this.numOfPrints=numOfPrints;
this.name=name;
}

@Override
public void run() {
for(int counter=0;counter<numOfPrints;counter++)
{
try {
// System.out.println(">>"+name+"<< "+cb.await());
cb.await();
System.out.println("["+name+"] "+startCounter);
cb.await();
//System.out.println("<<"+name+">> "+cb.await());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
startCounter+=3;
}
}

}

输出

[Three] 3
[One] 1
[Two] 2
[One] 4
[Two] 5
[Three] 6
[Two] 8
[One] 7
[Three] 9
[One] 10
[Two] 11
[Three] 12
[Two] 14
[One] 13
[Three] 15
[One] 16
[Two] 17
[Three] 18
[Two] 20
[One] 19
[Three] 21
[One] 22
[Two] 23
[Three] 24
[Two] 26
[One] 25
[Three] 27
[One] 28
[Two] 29
[Three] 30

谁能帮我解答一下?

类似问题 Thread Synchronization - Synchronizing three threads to print 012012012012..... not working

最佳答案

正如其他人已经提到的,CyclicBarrier 并不是完成这项任务的最佳工具。

我也同意这样的观点,即解决方案是链接线程并始终让一个线程设置下一个线程。

这是一个使用信号量的实现:

import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.Semaphore;

public class PrintNumbersWithSemaphore implements Runnable {

private final Semaphore previous;

private final Semaphore next;

private final int[] numbers;

public PrintNumbersWithSemaphore(Semaphore previous, Semaphore next, int[] numbers) {
this.previous = previous;
this.next = next;
this.numbers = numbers;
}

@Override
public void run() {

for (int i = 0; i < numbers.length; i++) {
wait4Green();

System.out.println(numbers[i]);

switchGreen4Next();
}
}

private void switchGreen4Next() {
next.release();
}

private void wait4Green() {
try {
previous.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

static public void main(String argv[]) throws InterruptedException, BrokenBarrierException {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(1);
Semaphore sem3 = new Semaphore(1);
sem1.acquire();
sem2.acquire();
sem3.acquire();
Thread t1 = new Thread(new PrintNumbersWithSemaphore(sem3, sem1, new int[] { 1, 4, 7 }));
Thread t2 = new Thread(new PrintNumbersWithSemaphore(sem1, sem2, new int[] { 2, 5, 8 }));
Thread t3 = new Thread(new PrintNumbersWithSemaphore(sem2, sem3, new int[] { 3, 6, 9 }));
t1.start();
t2.start();
t3.start();
sem3.release();

t1.join();
t2.join();
t3.join();
}

}

这是另一个,在我看来,使用 CyclicBarrier 的实现相当麻烦:

import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.CyclicBarrier;

public class PrintNumbersWithCyclicBarrier implements Runnable {

private final CyclicBarrier previous;

private final CyclicBarrier next;

private final int[] numbers;

public PrintNumbersWithCyclicBarrier(CyclicBarrier previous, CyclicBarrier next, int[] numbers) {
this.previous = previous;
this.next = next;
this.numbers = numbers;
}

@Override
public void run() {

for (int i = 0; i < numbers.length; i++) {
wait4Green();

System.out.println(numbers[i]);

switchRed4Myself();

switchGreen4Next();
}
}

private void switchGreen4Next() {
try {
next.await();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

private void switchRed4Myself() {
previous.reset();
}

private void wait4Green() {
try {
previous.await();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

static public void main(String argv[]) throws InterruptedException, BrokenBarrierException {
CyclicBarrier cb1 = new CyclicBarrier(2);
CyclicBarrier cb2 = new CyclicBarrier(2);
CyclicBarrier cb3 = new CyclicBarrier(2);
Thread t1 = new Thread(new PrintNumbersWithCyclicBarrier(cb3, cb1, new int[] { 1, 4, 7 }));
Thread t2 = new Thread(new PrintNumbersWithCyclicBarrier(cb1, cb2, new int[] { 2, 5, 8 }));
Thread t3 = new Thread(new PrintNumbersWithCyclicBarrier(cb2, cb3, new int[] { 3, 6, 9 }));
t1.start();
t2.start();
t3.start();
cb3.await();

t1.join();
t2.join();
t3.join();
}

}

关于java - 同步三个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26165549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com