ゞ沉默是金ゞ

          魚(yú)離不開(kāi)水,但是沒(méi)有說(shuō)不離開(kāi)哪滴水.
          posts - 98,comments - 104,trackbacks - 0
          <2012年8月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          常用鏈接

          留言簿(3)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          Today in next part of the series we will talk about How to communicate among threads using Lock and Condition Objects.


          In traditional Java - If we need to communicate among threads, we syncronize code and use "wait" and "notify" methods  of Object class.
          From Java 5.0 and above - Lock interface provides an easier implmentation for synchronization and Condition class can be used to wait and notify threads.


          Lock has several important methods such as "lock", "tryLock", "lockInterruptibly" etc, whereas Condition has "await", "signal", 'signalAll" etc. In this article we will demonstrate the usage of 3 methods - "lock" (from Lock interface), "await", "signal" (from Condition Class).


          Lets try to visualize a scenario here - Assume we have 2 process "Reader" and "Writer". Writer writes on a file and Reader reads from a file. we want to add a listener to writer object so that whenever writer writes anything on a file, "Reader" will be called and it will read the same data. Before we look into codes lets look at the some important points to use Lock and Condition-


          1) Lock is an Interface, the most common implementation class is ReentrantLock. Others two are - ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock
          2) Condition Object is always retrieved from Lock object. For example - Condition condition = lock.newCondition( );
          3) One of the best practice to use Lock is-
          Lock lockObj = new ReentrantLock( );
                              lockObj.lock( );
                                  try{
          .... code..
                                     }finally{
                                lockObj.unlock( );
                                     }
          4) condition.await, condition.signal, condition.signalAll methods should only be called once you have acquired the lock by - lockObj.lock( ).
          In our example, the design of the class will be something like this -
          > One lock Object == fileLock
          > One condition Object = condition = fileLock.newCondition


          Pseudo code for Writer Thread 
          // GET the LOCK
          try{
            // -- In  the Loop untill EXIT---
               //Write on the file
               // Signal the READER
               //If EXIT signal then exit else "WAIT for READER to SIGNAL"
           }finally{
            // RELEASE the LOCK
           }
          pseudo code for Reader Thread 
          // GET the LOCK
          try{
            // -- In  the Loop untill EXIT---
               //Read from the file
               // Signal the WRITER
               // If EXIT signal - then exit else "WAIT for WRITER to SIGNAL"
           }finally{
            // RELEASE the LOCK
           }


          package com.jovialjava.blog.threads;

          import java.io.BufferedReader;
          import java.io.File;
          import java.io.FileReader;
          import java.io.PrintWriter;
          import java.security.SecureRandom;
          import java.util.concurrent.ExecutorService;
          import java.util.concurrent.Executors;
          import java.util.concurrent.locks.Condition;
          import java.util.concurrent.locks.Lock;
          import java.util.concurrent.locks.ReentrantLock;

          public class LockExample {

              
          private static final String fileName = "LockExample.txt";
              
          private static final String EXIT_FLAG = "BYE";
              
          private static final int NO_OF_LINES = 10;
              
          private static final Lock fileLock = new ReentrantLock();
              
          private static final Condition condition = fileLock.newCondition();
              
          private static final ExecutorService executorPool = Executors.newFixedThreadPool(2);

              
          public static void main(String args) {
                  Runnable fileWriter 
          = new FileWrite();
                  Runnable fileReader 
          = new FileRead();
                  executorPool.submit(fileReader);
                  executorPool.submit(fileWriter);
                  executorPool.shutdown();
              }

              
          /**
               * This thread will write on a file and inform the reader thread to read it.
               * If it has not written the EXIT flag then it will go into wait stage and
               * will wait for READER to signal that it safe to write now.
               
          */
              
          public static class FileWrite implements Runnable {

                  
          public void run() {
                      
          try {
                          fileLock.lock();
                          
          for (int i = 0; i < NO_OF_LINES; i++) {
                              PrintWriter writer 
          = new PrintWriter(new File(fileName));
                              
          if (i != NO_OF_LINES - 1) {
                                  
          int random = new SecureRandom().nextInt();
                                  System.out.println(
          "WRITER WRITING " + random);
                                  writer.println(random);
                                  writer.close();
                                  
          // signallng to READER that its safe to read now.
                                  condition.signal();
                                  System.out.println(
          "Writer waiting");
                                  condition.await();
                              } 
          else {
                                  writer.println(EXIT_FLAG);
                                  System.out.println(
          "WRITER EXITING ");
                                  writer.close();
                                  
          // AS it was an exit flag so no need to wait, just
                                  
          // signal the reader.
                                  condition.signal();
                              }
                          }
                      } 
          catch (Exception e) {
                          System.out.println(
          "!!!!!!!!!!!!!!!!!!!!!!!!EXCEPTION!!!!!!!!!!!!!!!!!!!!!!!!");
                          e.printStackTrace();
                      } 
          finally {
                          fileLock.unlock();
                          
          // Delete the file, require in case if one wants to run demo
                          
          // again.
                          File file = new File(fileName);
                          file.delete();
                          
          try {
                              file.createNewFile();
                          } 
          catch (Exception e) {
                          }
                      }
                  }
              }

              
          /**
               * This thread will read from the file and inform the writer thread to write
               * again. If it has not read the EXIT flag then it will go into wait stage
               * and will wait for WRITER to signal that it safe to read now.
               
          */
              
          public static class FileRead implements Runnable {

                  
          public void run() {
                      String data 
          = null;
                      fileLock.lock();
                      
          try {
                          
          while (true) {
                              BufferedReader reader 
          = new BufferedReader(new FileReader(fileName));
                              data 
          = reader.readLine();
                              System.out.println(
          "READ DATA - " + data);
                              reader.close();
                              
          if (data == null || !data.equals(EXIT_FLAG)) {
                                  condition.signalAll();
                                  System.out.println(
          "Reader Waiting");
                                  condition.await();
                              } 
          else {
                                  System.out.println(
          "READER EXITING");
                                  condition.signal();
                                  
          break;
                              }
                          }
                      } 
          catch (Exception e) {
                          System.out.println(
          "!!!!!!!!!!!!!!!!!!!!!!!!EXCEPTION!!!!!!!!!!!!!!!!!!!!!!!!");
                          e.printStackTrace();
                      } 
          finally {
                          fileLock.unlock();
                      }
                  }
              }
          }
          posted on 2012-08-06 10:38 ゞ沉默是金ゞ 閱讀(786) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Java SE
          主站蜘蛛池模板: 东山县| 城步| 乐安县| 达州市| 灯塔市| 英吉沙县| 邵阳市| 怀仁县| 双鸭山市| 诸城市| 南宁市| 邵东县| 正阳县| 铁力市| 宝清县| 沧源| 广河县| 从江县| 天峨县| 滨海县| 巴林左旗| 南投县| 全州县| 霍邱县| 吴忠市| 遂平县| 枣强县| 衡阳县| 长子县| 盐边县| 虎林市| 利川市| 伊宁市| 喀喇沁旗| 贡觉县| 林甸县| 常州市| 长岭县| 姜堰市| 静安区| 安达市|