java:java_util_concurrent

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
java:java_util_concurrent [2017/03/21 11:19]
gthanos [ReadWriteLock]
java:java_util_concurrent [2017/03/21 12:13]
gthanos [Υλοποίηση μίας διασυνδεδεμένης λίστας η οποία είναι συγχρονισμένη]
Line 11: Line 11:
  
 Ένα //blocking queue// είναι μία ουρά μηνυμάτων (//queue//) στην οποία μπορούν να γράφουν ή να διαβάζουν από αυτή με ασφάλεια δύο ή περισσότερα νήματα. Όταν η ουρά είναι άδεια και ένα νήμα επιχειρήσει να διαβάσει αυτό μπλοκάρει μέχρι κάποιο άλλο νήμα να γράψει στην ουρά. Αντίστοιχα, όταν ένα νήμα επιχειρεί να γράψει σε μία γεμάτη ουρά το νήμα μπλοκάρει μέχρι να ελευθερωθεί μία θέση στην ουρά μηνυμάτων από κάποιο άλλο νήμα που διάβασε. Στο παρακάτω σχήμα βλέπετε την σχηματική αναπαράσταση ενός blocking queue.  Ένα //blocking queue// είναι μία ουρά μηνυμάτων (//queue//) στην οποία μπορούν να γράφουν ή να διαβάζουν από αυτή με ασφάλεια δύο ή περισσότερα νήματα. Όταν η ουρά είναι άδεια και ένα νήμα επιχειρήσει να διαβάσει αυτό μπλοκάρει μέχρι κάποιο άλλο νήμα να γράψει στην ουρά. Αντίστοιχα, όταν ένα νήμα επιχειρεί να γράψει σε μία γεμάτη ουρά το νήμα μπλοκάρει μέχρι να ελευθερωθεί μία θέση στην ουρά μηνυμάτων από κάποιο άλλο νήμα που διάβασε. Στο παρακάτω σχήμα βλέπετε την σχηματική αναπαράσταση ενός blocking queue. 
-{{  :java:design_and_implement_a_blocking_queue-600x0.png?450  }}  + 
 +{{ :java:blockingqueue.png? }} 
  
 Οι βασικές μέθοδοι που υποστηρίζονται από ένα //blocking queue// είναι οι εξής: Οι βασικές μέθοδοι που υποστηρίζονται από ένα //blocking queue// είναι οι εξής:
Line 77: Line 78:
 ===== Παραδείγματα Χρήσης Εργαλείων Συγχρονισμού ===== ===== Παραδείγματα Χρήσης Εργαλείων Συγχρονισμού =====
  
-==== Blocking Queue με locks ====+===== Blocking Queue με Locks =====
  
 Ας υποθέσουμε ότι έχετε το αρχείο κειμένου {{:java:largedict.txt.zip|largedict.txt}} για το οποίο θέλετε να κάνετε τα εξής. Έχετε **Ν** νήματα που διαβάζουν από το αρχείο και **Μ** νήματα που στο νέο αρχείο. Θέλετε το νέο αρχείο που θα γραφεί να είναι ίδιο με το αρχικό αρχείο που διαβάστηκε. Το αρχείο κειμένου διαβάζεται και γράφεται γραμμή-γραμμή. Ας υποθέσουμε ότι έχετε το αρχείο κειμένου {{:java:largedict.txt.zip|largedict.txt}} για το οποίο θέλετε να κάνετε τα εξής. Έχετε **Ν** νήματα που διαβάζουν από το αρχείο και **Μ** νήματα που στο νέο αρχείο. Θέλετε το νέο αρχείο που θα γραφεί να είναι ίδιο με το αρχικό αρχείο που διαβάστηκε. Το αρχείο κειμένου διαβάζεται και γράφεται γραμμή-γραμμή.
  
-Για την επικοινωνία μεταξύ αναγνωστών και εγγραφέων θα χρησιμοποιηθεί ένα blocking queue με σχετικά περιορισμένη χωρητικότητα **Κ**, όπου **K < min(M,N)**. Επίσης για την υλοποίηση του συγχρονισμού διαθέτουμε δύο κλειδαριές **α)** μία κλειδαριά η οποία βεβαιώνει ότι μόνο ένα νήμα μπορεί να γράψει στο Blocking Queue.+Για την επικοινωνία μεταξύ αναγνωστών και εγγραφέων θα χρησιμοποιηθεί ένα blocking queue με σχετικά περιορισμένη χωρητικότητα **Κ**, όπου **K < min(M,N)**. Επίσης για την υλοποίηση του συγχρονισμού διαθέτουμε δύο κλειδαριές **α)** μία κλειδαριά η οποία βεβαιώνει ότι μόνο ένα νήμα διαβάζει από το αρχείο και γράφει στο //Blocking Queue// και **β)** μία κλειδαριά η οποία βεβαιώνει ότι μόνο ένα νήμα διαβάζει από το //Blocking Queue// και γράφει στο νέο αρχείο.
  
-Δείτε το παρακάτω παράδειγμα κώδικα που υλοποιεί τον συγχρονισμό μεταξύ των νημάτων ανάγνωσης και εγγραφής.+<WRAP tip 80% center round> 
 +Για τον παρακάτω παράδειγμα κώδικα που υλοποιεί τον συγχρονισμό μεταξύ των νημάτων ανάγνωσης και εγγραφής, μεταγλωττίστε και εκτελέστε αρχικά απενεργοποιώντας τις δύο κλειδαριές και στη συνέχεια ενεργοποιώντας τες. Ποια διαφορά παρατηρείτε στο τελικό αρχείο στην μία και την άλλη περίπτωση. Σε τι οφείλεται η διαφορά αυτή; 
 +</WRAP>
  
-<code java UtilConcurrentDemo1.java>+<code java BlockingQueueWithLocks.java>
 import java.util.concurrent.*; import java.util.concurrent.*;
 import java.util.concurrent.locks.*; import java.util.concurrent.locks.*;
 import java.io.*; import java.io.*;
  
-public class UtilConcurrentDemo1 {  +public class BlockingQueueWithLocks {  
      
   public static void main(String args[]) {   public static void main(String args[]) {
Line 110: Line 113:
     }     }
          
-    boolean useLocks = false;+    boolean useLocks = true;
          
     ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(2);     ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
Line 254: Line 257:
 ==== Υλοποίηση μίας διασυνδεδεμένης λίστας η οποία είναι συγχρονισμένη ==== ==== Υλοποίηση μίας διασυνδεδεμένης λίστας η οποία είναι συγχρονισμένη ====
  
-Όπως ίσως θα γνωρίζετε η διασυνδεδεμένες λίστες που υπάρχουν στο πακέτο java.util δεν είναι συγχρονισμένες, δηλαδή δεν μπορούν να προσπελαστούν ταυτόχρονα από δύο ή περισσότερα νήματα. Προκειμένου να μπορούμε να προσπελάσουμε μία λίστα από περισσότερα του ενός νήματα δημιουργούμε την κλάση SynchronizedList η οποία χρησιμοποιεί ένα [[http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.ReadLock.html|java.util.concurrent.locks.ReentrantLock.ReadLock]] για διάβασμα και ένα [[http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.ReadLock.html|ReentrantReadWriteLock.WriteLock.html]] για μεταβολή του περιεχομένου της λίστας.+Όπως ίσως θα γνωρίζετε η διασυνδεδεμένες λίστες που υπάρχουν στο πακέτο **[[https://docs.oracle.com/javase/7/docs/api/java/util/package-frame.html|java.util]]** δεν είναι συγχρονισμένες, δηλαδή δεν μπορούν να παρέχουν καμία εγγύηση ότι εάν προσπελαστούν ταυτόχρονα από δύο ή περισσότερα νήματα η δομή θα διατηρήσει την εσωτερική της συνοχή και το περιεχόμενο της θα είναι σωστό. Προκειμένου να μπορούμε να προσπελάσουμε μία λίστα από περισσότερα του ενός νήματα δημιουργούμε την κλάση SynchronizedList η οποία χρησιμοποιεί ένα [[http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.ReadLock.html|java.util.concurrent.locks.ReentrantLock.ReadLock]] για διάβασμα και ένα [[http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.ReadLock.html|ReentrantReadWriteLock.WriteLock.html]] για μεταβολή του περιεχομένου της λίστας.
  
 Δείτε πως διαμορφώνεται η κλάση καθώς και ένα παράδειγμα χρήσης της κλάσης αυτής. Δείτε πως διαμορφώνεται η κλάση καθώς και ένα παράδειγμα χρήσης της κλάσης αυτής.
  
-<code java UtilConcurrentDemo2.java>+<code java SynchronizedList.java>
 import java.util.*; import java.util.*;
 import java.util.concurrent.*; import java.util.concurrent.*;
Line 429: Line 432:
   Random rand;   Random rand;
   SynchronizedList<Integer> list;   SynchronizedList<Integer> list;
 +  //ArrayList<Integer> list;
      
   public ListModifierThread(SynchronizedList<Integer> list) {   public ListModifierThread(SynchronizedList<Integer> list) {
 +  //public ListModifierThread(ArrayList<Integer> list) {
     this.list = list;     this.list = list;
     rand = new Random( new Date().getTime() );     rand = new Random( new Date().getTime() );
Line 439: Line 444:
       list.add( rand.nextInt(1000) );       list.add( rand.nextInt(1000) );
    
-    list.listWriteLock()    +    for(int i=0i<1000; i++
-    while( list.size() > 0 )  +      list.remove(0);
-      System.out.println( list.remove( list.size()-1 ) );+
          
     if( list.isEmpty() )      if( list.isEmpty() ) 
Line 447: Line 451:
     else     else
       System.out.println( this.getName() +": list is NOT empty!");           System.out.println( this.getName() +": list is NOT empty!");    
-    list.listWriteUnlock(); 
   }   }
 } }
Line 454: Line 457:
   public static void main(String []args) {   public static void main(String []args) {
     SynchronizedList<Integer> list = new SynchronizedList<>();     SynchronizedList<Integer> list = new SynchronizedList<>();
 +    //ArrayList<Integer> list = new ArrayList<>();
          
     for(int i=0; i<10; i++) {     for(int i=0; i<10; i++) {
java/java_util_concurrent.txt · Last modified: 2017/03/21 14:36 by gthanos