Ο σηματοφορέας είναι μία οντότητα συγχρονισμού μεταξύ ανεξάρτητων ροών εργασίας. Ας υποθέσουμε ότι έχουμε ένα buffer Ν θέσεων μηνυμάτων μέσω του οποίου επικοινωνούν δύο διεργασίες. Αρχικά το buffer είναι άδειο, η διεργασία Α προσθέτει μηνύματα στο buffer και η διεργασία Β τα διαβάζει και τα αφαιρεί από το buffer. Η διαδικασία υπόκειται στους εξής περιορισμούς:
Ας υποθέσουμε ότι ορίζουμε ένα σηματοφορέα ως εξής. Αρχικά ο σηματοφορέας έχει μία αρχική ακέραια τιμή μεγαλύτερη ή ίση με το μηδέν. Κάθε φορά που λαμβάνουμε ένα resource (θα εξηγηθεί) η τιμή του σηματοφορέα μειώνεται κατά 1, ενώ κάθε φορά που επιστρέφουμε ένα resource η τιμή αυξάνεται κατά 1. Εάν ο σηματοφορέας λάβει την τιμή μηδέν δεν μπορούμε να λάβουμε άλλο resource και η διεργασία που προσπαθεί να λάβει το resource μπλοκάρει.
Για το παραπάνω πρόβλημα ορίζουμε δύο σηματοφορείς (write και read) ως εξής:
Όταν το buffer είναι άδειος ο σηματοφορέας readSem έχει την τιμή 0 και η διαδικασία B μπλοκάρει μέχρι να γραφεί κάτι σε αυτό. Εάν το buffer είναι γεμάτο ο σηματοφορέας write έχει την τιμή 0 και η διαδικασία A μπλοκάρει μέχρι να διαβαστεί κάτι από το buffer.
Ο κώδικας για το γράψιμο και το διάβασμα στο buffer δίνεται σχηματικά ως εξής:
// γράψιμο writeSem.down() buffer.write(msg); readSem.up(); // διάβασμα String msg; readSem.down() msg = buffer.read(); writeSem.up();
Ο κώδικας για ένα σηματοφορέα γενικής χρήσης δίνεται παρακάτω:
public class Semaphore { byte value = 1; public Semaphore(byte init_value) { value = init_value; } public synchronized void down() { while(value==0) { try { wait(); } catch(InterruptedException ex) {} } value--; } public synchronized void up() { value++; notifyAll(); } }