Skip to content

Latest commit

 

History

History
171 lines (130 loc) · 16.2 KB

README - el.md

File metadata and controls

171 lines (130 loc) · 16.2 KB

javaThreads

Multiply Table Είναι γνωστό από τη Γραμμική Άλγεβρα ότι μπορούμε να πολλαπλασιάσουμε έναν πίνακα με ένα διάνυσμα από δεξιά, αρκεί το πλήθος των στηλών του πίνακα να είναι ίσο με το πλήθος των γραμμών του διανύσματος. Για παράδειγμα αν έχουμε έναν πίνακα Α με διαστάσεις n x m και ένα διάνυσμα v με διαστάσεις m x 1, τότε το γινόμενο Α * v ισούται με ένα διάνυσμα n x 1 με εφαρμογή της γνωστής μεθόδου πολλαπλασιασμού πίνακα με διάνυσμα. Ένα παράδειγμα δίνεται στο ακόλουθο σχήμα.

Αν υποθέσουμε ότι διαθέτουμε k νήματα, όπου το k είναι δύναμη του 2 και ο πίνακας έχει διαστάσεις n x m όπου το n είναι επίσης δύναμη του 2 και n > k, να σχεδιάσετε μία λύση που να υπολογίζει το γινόμενο Α * v χρησιμοποιώντας τα k νήματα με τον καλύτερο δυνατό τρόπο. Το πρόγραμμά σας θα πρέπει να “γεμίζει” τον πίνακα Α και το διάνυσμα v με τυχαίους αριθμούς μεταξύ 0 και 10.

Ποιές οι μετρήσεις χρόνου για 1, 2, 4 και 8 νήματα.


SimpsonsScript Δίνεται ένα αρχείο με όνομα “simpsons_script_lines.csv” το οποίο περιέχει τους διαλόγους από όλα τα επεισόδια της σειράς. Σε κάθε γραμμή του αρχείου περιλαμβάνονται στοιχεία, όπως το επεισόδιο, ο χαρακτήρας που μιλάει, η τοποθεσία και το ίδιο το κείμενο.

Ένα πρόγραμμα σε JAVA που αρχικά θα φορτώνει τις γραμμές του αρχείου σε ένα πίνακα, και στη συνέχεια θα δημιουργεί k νήματα, κάθε ένα από τα οποία θα αναλαμβάνει την επεξεργασία ενός τμήματος του πίνακα. Το πρόγραμμα θα υπολογίζει τα ακόλουθα:

  1. το επεισόδιο στο οποίο οι διάλογοι είχαν το μεγαλύτερο πλήθος λέξεων
  2. την τοποθεσία όπου έλαβαν χώρα οι περισσότερες στιχομυθίες
  3. για κάθε έναν από τους χαρακτήρες Bart, Homer, Margie και Lisa, να εκτυπώσετε την πιο κοινή λέξη που χρησιμοποιούν (από 5 χαρακτήρες και πάνω) καθώς και πόσες φορές τη χρησιμοποίησαν.

Ποιές οι μετρήσεις χρόνου για 1, 2, 4 και 8 νήματα.


Ipsum Thread Count Θα χρησιμοποιήσουμε ανοιχτά APIs τα οποία μας δίνουν πληροφορίες ως κείμενο και από αυτά θα εξάγουμε διάφορα στατιστικά. Τα ακόλουθα APIs, παράγουν απλό κείμενο με την κλήση της HTTP μεθόδου GET: https://loripsum.net/api/10/plaintext http://metaphorpsum.com/paragraphs/10

Πρόγραμμα σε JAVA το οποίο θα χρησιμοποιεί 1, 2, 4 ή 8 νήματα για να πραγματοποιήσει ένα αριθμό κλήσεων k ανά νήμα, σε ένα APIs (θα δίνεται παραμετρικά) για να υπολογίσει τα ακόλουθα:

  1. το μέσο όρο μήκους των λέξεων του κειμένου από όλα τα κείμενα που παράχθηκαν. Σε κάθε εκτέλεση (k-κλήσεις επί n-νήματα) θα εκτυπώνεται δηλαδή ένα νούμερο.
  2. το ποσοστό εμφανίσεων των χαρακτήρων του αγγλικού αλφαβήτου από όλα τα κείμενα που παράχθηκαν. Σε κάθε εκτέλεση (k-κλήσεις επί n-νήματα) θα εκτυπώνονται δηλαδή 26 νούμερα, το άθροισμα των οποίων θα είναι 100.

Να αγνοήσετε τα σημεία στίξης. Μετρήσεις χρόνου για 1, 2, 4 και 8 νήματα


Shopping With Threads Συγχρονισμό και αμοιβαίο αποκλεισμό.

Θα προσομοιώσουμε τη λειτουργία ενός καταστήματος πώλησης ενδυμάτων. Η λειτουργία του καταστήματος βασίζεται στους εξής κανόνες που πρέπει να υλοποιήσουμε:

  • Στο κατάστημα μπορούν να βρίσκονται ταυτόχρονα το πολύ 40 άτομα.
  • Υπάρχουν δύο χώροι δοκιμής ρούχων, ένας για γυναίκες, ένας για άντρες και το κάθε δοκιμαστήριο διαθέτει 5 ξεχωριστά δωμάτια.
  • Στο κατάστημα υπάρχει ένα ταμείο το οποίο όμως λόγω των περιορισμών COVID δεν επιτρέπει να βρίσκονται στην ουρά πάνω από 10 άτομα.

Να υλοποιήσετε την παραπάνω λειτουργικότητα με χρήση σημαφόρων υποθέτοντας ότι το ποσοστό γυναικών-ανδρών στο κατάστημα είναι 50%-50%, θεωρώντας ότι ο χρόνος εξυπηρέτησης στο ταμείο είναι σταθερός από τη στιγμή που είναι η σειρά μας να πληρώσουμε (π.χ., 5 δευτερόλεπτα) και επίσης θεωρώντας ότι το κάθε άτομο χρειάζεται από 3 έως 10 δευτερόλεπτα για να δοκιμάσει τα ρούχα στο δοκιμαστήριο πριν πάει στο ταμείο. Επίσης να θεωρήσετε ότι κάθε 2 έως 5 δευτερόλεπτα εισέρχεται και ένας νέος πελάτης στο κατάστημα για να δοκιμάσει και να αγοράσει ρούχα.


Σχεδιασμός και υλοποίηση κατανεμημένων συστημάτων μικρής κλίμακας, χρησιμοποιώντας τεχνικές επικοινωνίας μεταξύ διεργασιών (interprocess communication).

Θα χρησιμοποιήσουμε Java Sockets για να συγχρονίσουμε διεργασίες που εκτελούνται σε διαφορετικά υπολογιστικά συστήματα.

Server Client HashTable Εφαρμογή που περιλαμβάνει επικοινωνία διεργασιών με TCP sockets. Server: Ο server αρχίζει τη λειτουργία του κατασκευάζοντας έναν άδειο πίνακα κατακερματισμού (hashtable) ο οποίος αποθηκεύει ζευγάρια της μορφής κλειδί-τιμή. Το μέγεθος του πίνακα είναι 2^20. Στη συνέχεια ανοίγει ένα socket στην πόρτα την οποία περνάμε ως παράμετρο στον constructor (π.χ. 8888, 9999, κλπ). Στη συνέχεια περιμένει να συνδεθεί κάποιος client. Client: Ο client αρχίζει τη λειτουργία του και προσπαθεί να συνδεθεί με το server στην πόρτα που έχουμε ορίσει. Πάλι, η πόρτα θα πρέπει να περνάει ως παράμετρος στον constructor του client.

Μετά την επιτυχή σύνδεση του client με τον server, ο server ξεκινάει νέο νήμα εξυπηρέτησης.

Ο client στέλνει στον server μία τριάδα τιμών (Α, Β, Γ), όπου το Α έχει μία από τις τιμές 0 (τέλος επικοινωνίας), 1 (insert), 2 (delete) και 3 (search), το Β είναι ένας ακέραιος αριθμός που δηλώνει το κλειδί και το Γ ένας ακέραιος αριθμός που δηλώνει την τιμή έχει το κλειδί.

Για παράδειγμα, αν ο client στείλει το ζεύγος (1,3,10), αυτό σημαίνει ότι ο server θα πρέπει να κάνει εισαγωγή του στοιχείου 3 στον πίνακα κατακερματισμού με τιμή 10. Μετά την επιτυχή εισαγωγή του στοιχείου ο server επιστρέφει την τιμή 1 στον client αλλιώς επιστρέφει 0. Αν ο client στείλει την εντολή (2,3) τότε θα πρέπει ο server να διαγράψει το στοιχείο με κλειδί 3 από τον πίνακα κατακερματισμού. Αν η διαγραφή είναι επιτυχής, ο server επιστρέφει την τιμή 1 αλλιώς επιστρέφει την τιμή 0. Τέλος αν ο client στείλει την εντολή (3,5) τότε ο server αναζητά το στοιχείο με κλειδί 5 στον πίνακα και επιστρέφει στον client την αντίστοιχη τιμή ή 0 αν το κλειδί δεν υπάρχει. Η σύνδεση καταργείται όταν ο client στείλει την εντολή (0,0). Οι εντολές διαβάζονται από το πληκτρολόγιο.


Server Client Producer Consumer Έστω ένα σύστημα διεργασιών που αποτελείται από διεργασίες τύπου consumer, producer και server οι οποίες επικοινωνούν με TCP sockets. Το σύστημα λειτουργεί ως εξής. Ο κάθε server διαθέτει μία ακέραια μεταβλητή (έστω storage) που καταγράφει το απόθεμα των προϊόντων που διαθέτει συνολικά. Η αρχική τιμή της μεταβλητής αυτής είναι ένας τυχαίος αριθμός μεταξύ 1 και 1000. Ο κάθε producer συνδέεται τυχαία σε έναν από τους servers και προσθέτει μία τυχαία τιμή Χ μεταξύ 10 και 100 στη μεταβλητή storage. Εάν η νέα τιμή της μεταβλητής storage ξεπεράσει το 1000, τότε ο αντίστοιχος server τυπώνει κάποιο μήνυμα στην οθόνη και η τιμή storage δεν ενημερώνεται. Στη συνέχεια, ο producer περιμένει ένα τυχαίο χρονικό διάστημα μεταξύ 1 και 10 δευτερολέπτων και συνδέεται στον επόμενο server επίσης με τυχαίο τρόπο. Ο κάθε consumer συνδέεται τυχαία σε έναν από τους servers και αφαιρεί μία τυχαία τιμή Υ μεταξύ 10 και 100 από τη μεταβλητή storage. Εάν η νέα τιμή του storage γίνει μικρότερη από 1, τότε ο αντίστοιχος server τυπώνει κάποιο μήνυμα στην οθόνη και η τιμή storage δεν ενημερώνεται. Στη συνέχεια, περιμένει ένα τυχαίο χρονικό διάστημα μεταξύ 1 και 10 δευτερολέπτων και συνδέεται στον επόμενο server επίσης με τυχαίο τρόπο.

Το πλήθος των servers πρέπει να είναι καθορισμένο από την αρχή, ωστόσο το πρόγραμμά θα πρέπει να μπορεί να λειτουργεί με οποιοδήποτε πλήθος servers, producers και consumers.

O κάθε server θα πρέπει να μπορεί να υποστηρίζει ταυτόχρονα πολλούς consumers και πολλούς producers, άρα θα πρέπει να υποστηρίζει multi-threading.

Σημείωση: Αν και το σύστημα αυτό μπορεί να λειτουργήσει σε κατανεμημένη μορφή (οι διεργασίες να βρίσκονται σε διαφορετικούς υπολογιστές με διαφορετικές IPs) υποθέστε ότι το σύστημα θα τρέξει στον ίδιο υπολογιστή (localhost). Άρα, μπορείς να ορίσεις για κάθε server διαφορετική πόρτα για τους producers και τους consumers. Για παράδειγμα, αν έχουμε 3 servers, μπορούμε να ορίσουμε τις πόρτες 8881, 8882, 8883 για να συνδέονται οι producers και τις πόρτες 9991, 9992, 9993 για να συνδέονται οι consumers.

Έτσι, θα μπορέσετε να επιλέγετε κάθε φορά έναν τυχαίο server για να συνδεθεί ο καθε producer και ο κάθε consumer.

Τρεις servers ή και περισσότεροι οριζόμενοι μέσω των port τους από σταθερά. Ο server ανοίγει ένα port για τους producer και ένα port για τους consumers και δέχεται τις εντολές. To κάθε Port είναι ένα thread. Κατάλληλη για κοινή χρήση μεταξύ των Server-Producer-Consumer η κλάση AtomicInteger. Οι δηλώσεις σε ποια port συνδέεται υπάρχουν οι σχετικές σταθερές CONSUMER και PRODUCER που ορίζεται στο main.

SERVER: Οι δηλώσεις με τις μεταβλητές του προβλήματος. Το πρόγραμμα έχει την κλάση Server όπου με Λ (1-9) όρισμα θα φτιάχνει Λ x2 port αντικείμενα για να λαμβάνει εντολές. Αντίστοιχα η κλάση user με τις μεθόδους producer/consumer θα ανοίγει Λ threads στα ports του server. Φτιάχνω κλάση ServerPort όπου κάθε port δουλεύει σαν server και μπορεί να ανοίγει δικά του threads.

CLIENT: O Producer/Consumer ξεκινάει threads που το καθένα επικοινωνεί με τους servers τυχαία. Καθόσον η διαφορά του Producer από τον consumer είναι μόνο η Port που συνδέονται, έφτιαξα την κλάση Client_Thread η οποία παίρνει όρισμα τις ανάλογες port και φτιάχνει Χ threads σε consumer/producers αλλάζοντας ports. Στις σταθερές περιλαμβάνονται τα port των Servers, η αναμονή μεταξύ των συνδέσεων και αν θέλουμε τις επιτρεπόμενες τιμές προς αποστολή. Η διαφορά του Producer από τον consumer είναι μόνο η port που συνδέονται. Για αυτό έφτιαξα σε νέο project τον Client. Χωρίς ή με λάθος ορίσματα συνδέεται στην default consumer port 9991. Αν δώσουμε πρώτο όρισμα το port που θέλουμε να συνδεθεί (πάνω από 7000), η κλάση μπορεί να εργαστεί ως producer ή consumer ανάλογα το port. Αν το πρώτο όρισμα είναι τα γράμματα “RP” (Random Producer) θα εργαστεί στα random port των producer ενώ αν το όρισμα είναι “RC” (Random Consumer) θα εργαστεί στα random port των consumer.