0

In a Code example it is said that a thread re-synchronization is based on signaling, using an indebted semaphore.

final Semaphore indebtedSemaphore = new Semaphore(1 - PROCESSOR_COUNT);

What is the purpose of this negative semaphore, with my notebook it would be initialized with -3

/**
 * Sums two vectors, distributing the work load into as many new child threads as there
 * are processor cores within a given system. Note that the added cost of thread
 * construction and destruction is higher than the gain of distributing the work for
 * practically any vector size.
 * @param leftOperand the first operand
 * @param rightOperand the second operand
 * @return the resulting vector
 * @throws NullPointerException if one of the given parameters is null
 * @throws IllegalArgumentException if the given parameters do not share the same length
 */
public static double[] add(final double[] leftOperand, final double[] rightOperand) {
    if (leftOperand.length != rightOperand.length) throw new IllegalArgumentException();
    final double[] result = new double[leftOperand.length];

    final int sectorWidth = leftOperand.length / PROCESSOR_COUNT;
    final int sectorThreshold = leftOperand.length % PROCESSOR_COUNT;
    final Semaphore indebtedSemaphore = new Semaphore(1 - PROCESSOR_COUNT);

    for (int threadIndex = 0; threadIndex < PROCESSOR_COUNT; ++threadIndex) {
        final int startIndex = threadIndex * sectorWidth + (threadIndex < sectorThreshold ? threadIndex : sectorThreshold);
        final int stopIndex  = startIndex  + sectorWidth + (threadIndex < sectorThreshold ? 1 : 0);
        final Runnable runnable = new Runnable() {
            public void run() {
                try {
                    for (int index = startIndex; index < stopIndex; ++index) {
                        result[index] = leftOperand[index] + rightOperand[index];
                    }
                } finally {
                    indebtedSemaphore.release();
                }
            }
        };
        // EXECUTOR_SERVICE.execute(runnable);                          // uncomment for managed thread alternative!
        new Thread(runnable).start();                                   // comment for managed thread alternative!
    }

    indebtedSemaphore.acquireUninterruptibly();
    return result;
}
user1477955
  • 1,652
  • 8
  • 23
  • 35
  • I'm assuming it was just the developer acknowledging that the semaphore would start with possibly negative values ? Not sure though. – Hunter McMillen Apr 24 '13 at 14:59
  • A negative semaphore means there is a negative amount of resources available. In other words, at that point, the application has a hold on all the resources and must release them before any other unit can acquire them. http://stackoverflow.com/questions/1221322/how-does-semaphore-work – Sotirios Delimanolis Apr 24 '13 at 15:00
  • @SotiriosDelimanolis why the -3 ? – user1477955 Apr 24 '13 at 15:02
  • @user1477955 You would have to show us more code, how the semaphore is being used. – Sotirios Delimanolis Apr 24 '13 at 15:02
  • if only 1 thread is active, there is no need to synchronize, therefore `-PROCESSOR_COUNT + 1`. – collapsar Apr 24 '13 at 15:04
  • @SotiriosDelimanolis I added the method above – user1477955 Apr 24 '13 at 15:08
  • @collapsar sorry, I do not understand, can you explain it in more detail? – user1477955 Apr 24 '13 at 15:10
  • 2
    you wrote, the semaphore is used to resync threads. so each thread 'terminating' (meaning it releases its processing resource) increments the semaphore. as soon as 1 thread remains, the sync'ing is complete (if the last thread, which in your example is the controller spawning everything else, would stop too, the whole process would terminate). – collapsar Apr 24 '13 at 15:17
  • 1
    Your main thread will wait at this line `indebtedSemaphore.acquireUninterruptibly();` until all other threads are done with their share of the semaphore. I'm guessing it is called `indebted` because it needs to pay back it's debt (count) before it can proceed. – Sotirios Delimanolis Apr 24 '13 at 15:48
  • can u please check my answer and vote it if i am right.. i know this question is based to your master project in Berlin.. so look at my answer and accept it for the poor guys .. that have to solve this exercise .. thx bro – Alexander Sidikov Pfeif Jun 21 '17 at 20:24

1 Answers1

0

comments in sourcecode->

public static double[] add (final double[] leftOperand, final double[] rightOperand) {
        if (leftOperand.length != rightOperand.length) throw new IllegalArgumentException();
        final double[] result = new double[leftOperand.length];
    //--------------------------------------------------------------
    //EXAMPLE: 3 Cores, vector length 10 
    //--------------------------------------------------------------

    final int sectorWidth = leftOperand.length / PROCESSOR_COUNT;
    final int sectorThreshold = leftOperand.length % PROCESSOR_COUNT;
    //indebtedSemaphore (-2) ..  to wait for a unindebted semaphore
    final Semaphore indebtedSemaphore = new Semaphore(1 - PROCESSOR_COUNT);

    //for each core a thread
    for (int threadIndex = 0; threadIndex < PROCESSOR_COUNT; ++threadIndex) {
        //ranges 0-4 , 4-7, 7-10  
        final int startIndex = threadIndex * sectorWidth + (threadIndex < sectorThreshold ? threadIndex : sectorThreshold);
        final int stopIndex = startIndex + sectorWidth + (threadIndex < sectorThreshold ? 1 : 0);
        final Runnable runnable = new Runnable() {
            public void run () {
                try {
                    for (int index = startIndex; index < stopIndex; ++index) {
                        result[index] = leftOperand[index] + rightOperand[index];
                    }
                } finally {
                    //semaphore dept:-2,-1,0,
                    indebtedSemaphore.release();
                }
            }
        };
        // EXECUTOR_SERVICE.execute(runnable);                          // uncomment for managed thread alternative!
        new Thread(runnable).start();                                   // comment for managed thread alternative!
    }

    //wait for unindebted semaphore 
    indebtedSemaphore.acquireUninterruptibly();
    return result;
}
Alexander Sidikov Pfeif
  • 2,418
  • 1
  • 20
  • 35