We currently have a project on threads and semaphores that I cannot for the life of me figure out because of certain restrictions.

Project Description Link : P4

The code we are supposed to modify is given here: http://cs.ua.edu/350/F2011/Assignments/ThreadSync.txt

We are only allowed to add semaphore statements to get the repeated AAABBC output. I originally thought it was easy because I used a simple for loop and so on, but later learned that you can't do this.

To get an idea of what were supposed to do, he gave us example code in class that is very similar to what is above where we were supposed to print "ABC" repeatedly.

The code for that in class example is below, while it is a little different, it still gets the point across of what to do.

Java Code:
import java.lang.Thread;
import java.util.concurrent.*;

public class ThreadSync
{
	private static Semaphore canPrintA = new Semaphore(1);
	private static Semaphore canPrintB = new Semaphore(0);
	private static Semaphore canPrintC = new Semaphore(0);

	private static int count = 100;
	
    public static void main( String[] args ) {
        System.out.printf( "Begin main thread\n");

        // create and name each runnable
        Runnable task1 = new PrintTaskA();
        Runnable task2 = new PrintTaskB();
        Runnable task3 = new PrintTaskC();

        Thread thread1 = new Thread( task1 );
        Thread thread2 = new Thread( task2 );
        Thread thread3 = new Thread( task3 );

        thread1.start();
        thread2.start();
        thread3.start();

        try {
	        thread1.join();
	        thread2.join();
	        thread3.join();
        }
        catch (InterruptedException ex) {
        	ex.printStackTrace();
        }
        
        System.out.printf( "End main thread\n");
    }
    
    public static class PrintTaskA implements Runnable 
    {
        public void run(){
    	    for (int i=0; i<count; i++) {
    	    	try {
    	    		canPrintA.acquire();
    	    	}
    	        catch (InterruptedException ex) {
    	        	ex.printStackTrace();
    	        }
    	        System.out.printf( "%2d: %s\n", i, "A");
   	    	canPrintB.release();
    	    }
        }
    }
    public static class PrintTaskB implements Runnable 
    {
        public void run(){
    	    for (int i=0; i<count; i++) {
    	    	try {
    	    		canPrintB.acquire();
    	    	}
    	        catch (InterruptedException ex) {
    	        	ex.printStackTrace();
    	        }
    	        System.out.printf( "%2d: %s\n", i, "B");
    	    	canPrintC.release();
    	    }
        }
    }
    public static class PrintTaskC implements Runnable 
    {
        public void run(){
    	    for (int i=0; i<count; i++) {
    	    	try {
    	    		canPrintC.acquire();
    	    	}
    	        catch (InterruptedException ex) {
    	        	ex.printStackTrace();
    	        }
    	        System.out.printf( "%2d: %s\n", i, "C");
    	    	canPrintA.release();
    	    }
        }
    }
}
You will notice:

-- PrintTaskA would call canPrintB.release() which would give permission to PrintTaskB to print B.

-- PrintTaskB would call canPrintC.release() which would give permission to PrintTaskC to print C.

-- PrintTaskC would call canPrintA.release() which would give permission to PrintTaskA to print A. This would complete the cycle.


These are the semaphores I have initiated for the actual project:

private static Semaphore canPrintA = new Semaphore(?);
private static Semaphore canPrintB = new Semaphore(?);
private static Semaphore canPrintC = new Semaphore(?);

The values are "?" for now because I am still not sure how to do it just yet. Again, the entire thing that confuses me is the fact we have to do this by ONLY adding semaphore statements.

Also, my teacher has given me the following hint:

"First, ignore printing A, and try to print BBCBBCBBC repeatedly. Then try to add AAA. When adding AAA, the flow should be
PrintA_thread --> PrintC_thread --> PrintB_thread --> PrintC_thread repeatedly instead of PrintA_thread --> PrintB_thread -->PrintC_thread as shown in the example I sent. Consider PrintC_thread as a coordinator."

I am realizing how huge of a post this is, but I could really use the help. The actual solution to this project is supposed to take 30 minutes but I can't figure it out.