0

im trying to understand the barrier problem. im still really new to programming but was presented with this problem in class to solve.

"I have to solve the barrier problem using counting semaphores. You can assume that there is a shared variable N which indicates the number of concurrent threads in the system. When the first N −1 threads arrive at the barrier, they should block until the Nth thread arrives, at which point all threads might proceed.

The shared counter variable can be used to keep track of the number of threads that have arrived and the semaphores mutex and barrier can be used to solve the synchronization problem."

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();
    }
}   

}

i tried to implement the pseudo code from the little book of semaphores. i called on this thread in main class and ran it but it gives an error about mutex.wait() for some reason. when i remove that bit of the code it runs but shows nothing. what exactly am i supposed to do for this problem?

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();
}

why does it output the rare one before the barrier is unlocked for all the threads? i think im close enough to solving this problem. is a race condition or something? CLICK TO SEE IMAGE

1 Answers1

0

Might be a bit late, but here is an implementation with a driver code that works. You have to garante mutual exclusion and keep track of the number of threads that arrive at the barrier.

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();
        }

    }
}
Eddoasso
  • 386
  • 2
  • 11