zoukankan      html  css  js  c++  java
  • java network programming Listener 例子 在loopmsn使用了

    The first advantage of the callback scheme over the polling scheme is that it doesn't waste so many CPU cycles. But a much more important advantage is that callbacks are more flexible and can handle more complicated situations involving many more threads, objects, and classes. For instance, if more than one object is interested in the result of the thread's calculation, the thread can keep a list of objects to call back. Particular objects can register their interest by invoking a method in the Thread or Runnable class to add themselves to the list. If instances of more than one class are interested in the result, a new interface can be defined that all these classes implement. The interface would declare the callback methods. If you're experiencing déjà vu right now, that's probably because you have seen this scheme before. This is exactly how events are handled in Swing, the AWT, and JavaBeans. The AWT runs in a separate thread from the rest of the program; components and beans inform you of events by calling back to methods declared in particular interfaces, such as ActionListener and PropertyChangeListener. Your listener objects register their interests in events fired by particular components using methods in the Component class, such as addActionListener( ) and addPropertyChangeListener( ). Inside the component, the registered listeners are stored in a linked list built out of java.awt.AWTEventMulticaster objects. It's easy to duplicate this pattern in your own classes. Example 5-9 shows one very simple possible interface class called DigestListener that declares the digestCalculated( ) method.

    Example 5-9. DigestListener interface
    public interface DigestListener {
    
    
    
      public void digestCalculated(byte[] digest);
    
    
    
    }

    Example 5-10 shows the Runnable class that calculates the digest. Several new methods and fields are added for registering and deregistering listeners. For convenience and simplicity, a java.util.Vector manages the list. The run( ) method no longer directly calls back the object that created it. Instead, it communicates with the private sendDigest( ) method, which sends the digest to all registered listeners. The run( ) method neither knows nor cares who's listening to it. This class no longer knows anything about the user interface class. It has been completely decoupled from the classes that may invoke it. This is one of the strengths of this approach.

    Example 5-10. The ListCallbackDigest class
    import java.io.*;
    
    import java.security.*;
    
    import java.util.*;
    
    
    
    public class ListCallbackDigest implements Runnable {
    
    
    
      private File input;
    
      List listenerList = new Vector( );
    
    
    
      public ListCallbackDigest(File input) {
    
       this.input = input;
    
      }
    
     
    
      public synchronized void addDigestListener(DigestListener l) {
    
        listenerList.add(l);
    
      }
    
      
    
      public synchronized void removeDigestListener(DigestListener l) {
    
        listenerList.remove(l);
    
      } 
    
        
    
      private synchronized  void sendDigest(byte[] digest) {
    
    
    
        ListIterator iterator = listenerList.listIterator( );
    
        while (iterator.hasNext( )) {
    
          DigestListener dl = (DigestListener) iterator.next( );
    
          dl.digestCalculated(digest);
    
        }
    
    
    
      }  
    
    
    
      public void run( ) {
    
    
    
        try {
    
          FileInputStream in = new FileInputStream(input);
    
          MessageDigest sha = MessageDigest.getInstance("SHA");
    
          DigestInputStream din = new DigestInputStream(in, sha);
    
          int b;
    
          while ((b = din.read( )) != -1) ;
    
          din.close( );
    
          byte[] digest = sha.digest( );
    
          this.sendDigest(digest);
    
        }
    
        catch (IOException ex) {
    
          System.err.println(ex);
    
        }
    
        catch (NoSuchAlgorithmException ex) {
    
          System.err.println(ex);
    
        }
    
        
    
      }
    
    
    
    }

    Finally, Example 5-11 is a main program that implements the DigestListener interface and exercises the ListCallbackDigest class by calculating digests for all the files named on the command line. However, this is no longer the only possible main program. There are now many more possible ways the digest thread could be used.

    Example 5-11. ListCallbackDigestUserInterface interface
    import java.io.*;
    
    
    
    public class ListCallbackDigestUserInterface implements DigestListener {
    
      
    
      private File input;
    
      private byte[] digest;
    
      
    
      public ListCallbackDigestUserInterface(File input) {
    
        this.input = input;
    
      }
    
      
    
      public void calculateDigest( ) {
    
        ListCallbackDigest cb = new ListCallbackDigest(input);
    
        cb.addDigestListener(this);
    
        Thread t = new Thread(cb);
    
        t.start( ); 
    
      }
    
      
    
      public void digestCalculated(byte[] digest) {  
    
        this.digest = digest;
    
        System.out.println(this);
    
      }
    
      
    
      public String toString( ) {
    
        String result = input.getName( ) + ": ";
    
        if (digest != null) {
    
          for (int i = 0; i < digest.length; i++) {
    
            result += digest[i] + " ";
    
          }  
    
        }
    
        else {
    
          result += "digest not available";
    
        }
    
        return result;
    
      }
    
      
    
      public static void main(String[] args) {
    
      
    
        for (int i = 0; i < args.length; i++) {    
    
          // Calculate the digest
    
          File f = new File(args[i]);
    
          ListCallbackDigestUserInterface d
    
           = new ListCallbackDigestUserInterface(f);
    
          d.calculateDigest( );
    
        } 
    
        
    
      }
    
    
    
    }
  • 相关阅读:
    Delphi代码获取网卡物理地址三种方法 本文来自Delphi之窗,原文地址:http://www.52delphi.com...
    SQL SERVER 中实现公历到农历的转换
    cxgrid相同列合并显示
    rzCheckList.ItemChecked[Index]就可以判断指定节点地状态.
    为什么PING域名得到IP与实际公网IP不符
    如何让sql server2005和sql server2000共存安装在同一机器上
    如何编译通过 Raize 5.3 中的 RzBorder.pas
    u6升级到u890的过程
    技术部门到底该如何管理才能“和谐”
    在CXGRID中如何让字段能以0.00的格式显示
  • 原文地址:https://www.cnblogs.com/goodloop/p/92506.html
Copyright © 2011-2022 走看看