“我必须使用计数信号量来解决屏障问题。您可以假设存在一个共享变量N,它指示系统中并发线程的数量。当前N-1个线程到达屏障时,它们应该阻塞直到第N个线程到达,此时所有线程都可以继续。
共享计数器变量可用于跟踪已到达的线程数,并且信号量互斥和屏障可用于解决同步问题。“
import java.util.concurrent.Semaphore;
public class BarrierSynchronization extends Thread {
int N;
int count;
Semaphore mutex;
Semaphore barrier;
public BarrierSynchronization ()
{
this.N = 5;
this.count = 0;
this.mutex = new Semaphore(1);
this.barrier = new Semaphore(0);
}
public void run()
{
try {
mutex.acquire();
count = count + 1;
System.out.println(Thread.currentThread().getName() + ": " + count);
mutex.release();
if (count == N)
{
barrier.release();
System.out.println("All " + count + " threads have reached the barrier. The barrier is now open" );
} // unblock one thread
barrier.acquire();
barrier.release();
System.out.println(Thread.currentThread().getName() + " has passed the barrier");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
我试图从信号量小书中实现伪代码。我在主类中调用了这个线程并运行它但由于某种原因它给出了关于mutex.wait()的错误。当我删除它运行的那段代码但没有显示任何内容。我应该为这个问题做些什么呢?
public class Main {
public static void main(String[] args) throws InterruptedException
{
BarrierSynchronization barrier = new BarrierSynchronization();
Thread bs1 = new Thread(barrier);
Thread bs2 = new Thread(barrier);
Thread bs3 = new Thread(barrier);
Thread bs4 = new Thread(barrier);
Thread bs5 = new Thread(barrier);
bs1.start();
bs2.start();
bs3.start();
bs4.start();
bs5.start();
}
答案 0 :(得分:0)
可能会有点晚,但是这是一个有效的驱动程序代码的实现。您必须确保相互排斥并跟踪到达屏障的线程数。
public class Barrier {
private int capacity;
private Semaphore s, exclusao, counter;
public Barrier(int capacity) {
this.capacity = capacity;
counter = new Semaphore(0);
s = new Semaphore(0);
exclusao = new Semaphore(1);
}
public void espera() throws InterruptedException {
exclusao.acquire();
if (counter.availablePermits() < capacity - 1) {
counter.release();
exclusao.release();
s.acquire();
} else {
exclusao.release();
System.out.println("RELEASE ALL");
for (int i = 0; i < capacity; i++) {
s.release();
}
}
}
}
class TesteThread extends Thread {
private Barrier b;
private long waitPeriod;
public TesteThread(long wait, Barrier b) {
this.b = b;
this.waitPeriod = wait;
System.out.println("Thread started" + this.getName());
}
public void espera() throws InterruptedException {
b.espera();
}
@Override
public void run() {
try {
System.out.println("Thread a dormir " + this.getName());
sleep(waitPeriod);
System.out.println("Thread a esperar " + this.getName());
espera();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class BarrierExample {
public static void main(String[] args) throws InterruptedException {
Barrier BR = new Barrier(5);
TesteThread[] teste = new TesteThread[5];
for (int i = 0; i < teste.length; i++) {
teste[i] = new TesteThread((long) (Math.random() * 1000), BR);
teste[i].start();
}
for (int i = 0; i < teste.length; i++) {
teste[i].join();
}
}
}`package examesFSO.exame2020_normal;
import java.util.concurrent.Semaphore;
public class Barrier {
private int capacity;
private Semaphore s, exclusao, counter;
public Barrier(int capacity) {
this.capacity = capacity;
counter = new Semaphore(0);
s = new Semaphore(0);
exclusao = new Semaphore(1);
}
public void espera() throws InterruptedException {
exclusao.acquire();
if (counter.availablePermits() < capacity - 1) {
counter.release();
exclusao.release();
s.acquire();
} else {
System.out.println("RELEASE ALL");
for (int i = 0; i < capacity; i++) {
s.release();
}
}
exclusao.release();
}
}
class TesteThread extends Thread {
private Barrier b;
private long waitPeriod;
public TesteThread(long wait, Barrier b) {
this.b = b;
this.waitPeriod = wait;
System.out.println("Thread instanciada " + this.getName());
}
public void espera() throws InterruptedException {
b.espera();
}
@Override
public void run() {
try {
System.out.println("Thread a dormir " + this.getName());
sleep(waitPeriod);
System.out.println("Thread a esperar " + this.getName());
espera();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class BarrierExample {
public static void main(String[] args) throws InterruptedException {
Barrier BR = new Barrier(5);
TesteThread[] teste = new TesteThread[5];
for (int i = 0; i < teste.length; i++) {
teste[i] = new TesteThread((long) (Math.random() * 1000), BR);
teste[i].start();
}
for (int i = 0; i < teste.length; i++) {
teste[i].join();
}
}
}