Threads και συμβατότητα κλάσεων GUI


Με την  Java μπορούμε να δημιουργήσουμε γραφικές διεπαφές χρήστη (Graphical User Interface) εν συντομία GUI. έχουμε δύο τρόπους στην διάθεσή μας. Ο πρώτος μέσα από Abstract Windowing Toolkit (AWT) και ο δεύτερος μέσα από το Swing.
H μετάβαση από τα AWT στα Swing GUI παρουσιάζει κάποιο μικρό πρόβλημα σε σχέση με τα Threads. Όλες οι AWT κλάσεις είναι συμβατές με τα threads (thread safe) ενώ οι Swing κλάσεις δεν είναι.

Τα  Threads μέσω των synchnonized μεθόδων, η Java επιτυγχάνει τoν συγχρονισμό των threads που έχουν πρόσβαση σε κάποιο κοινό αντικείμενο. Οι AWT μέθοδοι συγχρονίζονται την στιγμή της αρχικοποίησης του αντίστοιχου αντικειμένου τους στην οθόνη. Έτσι εμποδίζονται πιθανά αδιέξοδα (deadlocks) που επιφέρουν το «κρέμασμα» εφαρμογών την στιγμή της εμφάνισης γραφικών αντικείμενων (πχ. buttons, panels, κλπ) στην οθόνη.

Ωστόσο όπως αναφέρθηκε και προηγουμένως οι swing κλάσεις δεν είναι thread-safe. Ο κώδικας
διαχείρισης γεγονότων στις Swing εφαρμογές εκτελείται μέσα από μια συγκεκριμένη thread η οποία ονομάζεται event-dispatching thread. Με αυτό τον τρόπο επιτυγχάνεται ο κώδικας ενός event handler να τελειώνει πριν την εκτέλεση του κώδικα ενός άλλου event handler. Για την αποφυγή πιθανού αδιεξόδου (deadlock), είναι απαραίτητο και τα Swing components να δημιουργούνται, τροποποιούνται και ερωτώνται για την κατάστασή τους μέσα από την eventdispatching thread. Με άλλα λόγια αν θέλουμε γραφικά Swing θα πρέπει να δημιουργήσουμε ένα thread που θα είναι υπεύθυνο να τα "τρέχει". 

Η παραπάνω εικόνα δείχνει ακριβώς πως μπορούν να ιεραρχηθούν τα treads μέσα σε μία εφαρμογή. στην περίπτωσή μας το tread 1 είναι και το νήμα που θα τρέξει το Swing GUI της εφαρμογής μας. Από εκεί και πέρα για το tread 2,  μπορεί να ακολουθηθεί όποιος συγχρονισμός κριθεί απαραίτητος από τον προγραμματιστή. δηλαδή είτε μπορεί να ακολουθήσει μια σειριακή ακολουθία είτε το tread 1  και trhead2 να "τρέχουν" παράλληλα με μια μικρή διαφορά χρονισμού( buffer).

Στις σύγχρονες εφαρμογές η δημιουργία νημάτων είναι απαραίτητη στην επιτάχυνση των λειτουργιών τους.  Φανταστείτε για παράδειγμα, μια εφαρμογή που ανοίγει σε GUI ενώ προσπαθεί να συνδεθεί στο διαδίκτυο για download ενός βίντεο. Η τόσο "απλή" εφαρμογή θα ήταν τρομερά χρονοβόρα και κουραστική χωρίς χρήση νημάτων.