java中的简单屏障同步

时间:2017-05-19 02:39:45

标签: java barrier

我试图了解障碍问题。我仍然是编程的新手,但在课堂上遇到了这个问题需要解决。

“我必须使用计数信号量来解决屏障问题。您可以假设存在一个共享变量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();
}

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 个答案:

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

    }
}