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( );
    
        } 
    
        
    
      }
    
    
    
    }
  • 相关阅读:
    解决electron-vue中无法使用Element的Tooltip组件
    解决Electron安装包下载慢的问题
    虚拟机VirtualBox 共享挂载问题:mount: /mnt/xxx: wrong fs type, bad option, bad superblock on xxx
    git 设置和取消代理
    (转载)数据库连接池到底应该设多大?这篇文章可能会颠覆你的认知
    MySQL主主复制+MMM实现高可用
    Mysql5.6主从热备配置
    java 启动 shell脚本
    redis批量删除key
    spring mvc异常统一处理(ControllerAdvice注解)
  • 原文地址:https://www.cnblogs.com/goodloop/p/92506.html
Copyright © 2011-2022 走看看