`
dicmo
  • 浏览: 66948 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Coder 爱翻译 How Tomcat Works 第六章

    博客分类:
  • j2ee
阅读更多
Chapter 6: Lifecycle

Catalina是由许多组件组成的。当Catalina启动时,这些组件也需要跟着启动。当Catalina停止,这些组件也必须得到被清理的机会。例如,当一个容器停止,它必须调用加载了的所有的servlet的destroy方法,session管理器必须把session对象保存到辅助存储器。一个统一的用来启动和停止组件的机制是通过实现org.apache.catalina.Lifecycle接口。

一个实现了Lifecycle接口的组件可以触发一个或许多事件:BEFORE_START_EVENT, START_EVENT, AFTER_START_EVENT, BEFORE_STOP_EVENT, STOP_EVENT和AFTER_STOP_EVENT。当通常一个启动组件时触发前三个事件,当停止组件时触发三个事件。一个事件由org.apache.catalina.LifecycleEvent类代表。最后,当然,如果一个Catalina组件想要能够触发事件,这里必须有事件监听器。事件监听器让你来处理这些事件的响应。一个监听器由org.apache.catalina.LifecycleListener接口代表。

这章将讨论Lifecycle, LifecycleEvent和LifecycleListener.

The Lifecycle Interface

Catalina的设计允许一个组件包含其他组件。例如:一个容器可以包含像loader、manager等一样的组件。一个父组件负责启动和停止它的子组件。Catalina的设计让所有组件处于一个父组件监控下,以便一个bootstrap类只需要启动一个单独的组件就可以启动它自己以及它的子组件。这个单独的start/stop机制是通过Lifecycle接口实现的。
Listing 6.1: The Lifecycle interface   
 
package org.apache.catalina;
public interface Lifecycle { 
   public static final String START_EVENT = "start"; 
   public static final String BEFORE_START_EVENT = "before_start"; 
   public static final String AFTER_START_EVENT = "after_start"; 
   public static final String STOP_EVENT = "stop"; 
   public static final String BEFORE_STOP_EVENT = "before_stop"; 
   public static final String AFTER_STOP_EVENT = "after_stop"; 
   public void addLifecycleListener(LifecycleListener listener); 
   public LifecycleListener[] findLifecycleListeners(); 
   public void removeLifecycleListener(LifecycleListener listener); 
   public void start() throws LifecycleException; 
   public void stop() throws LifecycleException; 
} 

在Lifecycle中最重要的方法是start和stop。一个组件提供这些方法的实现,所以它的父组件可以来启动可停止它。其它三个与监听器相关的方法::addLifecycleListener, findLifecycleListeners, 和removeLifecycleListener。一个组件可以有监听器。这些监听器负责监听在这个组件中的事件是否发生。当一个事件触发,监听器会处理这个响应的事件。   这六个事件的名字可以通过一个Lifecycle实例在它接口中定义的public static final Strings来触发。

The LifecycleEvent Class

org.apache.catalina.LifecycleEvent类代表一个生命周期事件:
Listing 6.2: The org.apache.catalinaLifecycleEvent interface   
 
package org.apache.catalina; 
import java.util.EventObject; 
public final class LifecycleEvent extends EventObject { 
   public LifecycleEvent(Lifecycle lifecycle, String type) { 
     this(lifecycle, type, null); 
   }
   public LifecycleEvent(Lifecycle lifecycle, String type, Object data) { 
 	 super(lifecycle);
     this.lifecycle = lifecycle; 
     this.type = type; 
     this.data = data; 
   } 
   private Object data = null; 
   private Lifecycle lifecycle = null; 
   private String type = null; 
   public Object getData() { 
     return (this.data); 
   } 
   public Lifecycle getLifecycle() { 
     return (this.lifecycle); 
   } 
   public String getType() { 
     return (this.type);
   } 
} 


The LifecycleListener Interface

org.apache.catalina.LifecycleListener接口代表一个生命周期监听器:
Listing 6.3: The org.apache.catalina.LifecycleListener interface   

package org.apache.catalina; 
import java.util.EventObject; 
public interface LifecycleListener { 
   public void lifecycleEvent(LifecycleEvent event); 
} 

这个接口唯一的方法是lifecycleEvent。在一个监听器负责的事件被触发时这个方法会被调用

The LifecycleSupport Class

一个组件实现了Lifecycle,且允许一个监听器注册它相关的事件必须提供事件处理的代码给Lifecycle接口的相关方法:addLifecycleListener, findLifecycleListeners和removeLifecycleListener。然后这个组件必须存储所有的监听器,把它们添加到一个数组或一个ArrayList或类似的对象。Catalina提供一个工具类让一个组件可以很简单地处理监听器和触发生命周期事件:org.apache.catalina.util.LifecycleSupport。
Listing 6.4: The LifecycleSupport class   
 
package org.apache.catalina.util; 
import org.apache.catalina.Lifecycle; 
import org.apache.catalina.LifecycleEvent; 
import org.apache.catalina.LifecycleListener;

public final class LifecycleSupport { 
   public LifecycleSupport(Lifecycle lifecycle) { 
     super(); 
     this.lifecycle = lifecycle; 
   }
   private Lifecycle lifecycle = null; 
   private LifecycleListener listeners[] = new LifecycleListener[0]; 
   public void addLifecycleListener(LifecycleListener listener) { 
     synchronized (listeners) { 
       LifecycleListener results[] =  new LifecycleListener[listeners.length + 1]; 
       for (int i = 0; i < listeners.length; i++) 
         results[i] = listeners[i];
         results[listeners.length] = listener; 
         listeners = results; 
     } 
   }
public LifecycleListener[] findLifecycleListeners() { 
     return listeners; 
   } 
   public void fireLifecycleEvent(String type, Object data) { 
     LifecycleEvent event = new LifecycleEvent(lifecycle, type, data); 
     LifecycleListener interested[] = null; 
     synchronized (listeners) { 
       interested = (LifecycleListener[]) listeners.clone(); 
     }
     for (int i = 0; i < interested.length; i++)
       interested[i].lifecycleEvent(event); 
   } 
   public void removeLifecycleListener(LifecycleListener listener) { 
     synchronized (listeners) { 
       int n = -1; 
       for (int i = 0; i < listeners.length; i++) {
         if (listeners[i] == listener) { 
           n = i; 
           break; 
         } 
       } 
       if (n < 0) 
         return; 
       LifecycleListener results[] = new LifecycleListener[listeners.length - 1];
       int j = 0; 
       for (int i = 0; i < listeners.length; i++) { 
          if (i != n) 
            results[j++] = listeners[i]; 
       } 
       listeners = results; 
     } 
   }
}

你看见LifecycleSupport类把所有的生命周期监听器存储到一个listeners的数组中,它开始是没有元素的。
private LifecycleListener listeners[] = new LifecycleListener[0];

当用addLifecycleListener方法添加一个监听器时,会创建一个新的数组。这个数组的元素大小是原数组大小的值加1。然后,原数组的所有元素会被复制到新数组中,这个新的监听器就被添加了。当使用removeLifecycleListener方法移除一个监听器时,也会创建一个新数组,这个数组的大小是原数组大小的值减1。然后,除了被移除的监听器外,其他所有元素会被复制到新数组中。

fireLifecycleEvent方法会触发一个生命周期事件。首先,它克隆监听器数组。然后,它调用数组中每一个成员的lifecycleEvent方法,并传递被触发的事件。

一个组件实现了Lifecycle可以使用LifecycleSupport类。例如, 在本章的应用中的SimpleContext类声明了下面的变量:
protected LifecycleSupport lifecycle = new LifecycleSupport(this);

要添加一个生命周期监听器,SimpleContext类调用LifecycleSupport类的addLifecycleListener方法:
public void addLifecycleListener(LifecycleListener listener) { 
   lifecycle.addLifecycleListener(listener); 
}

要移除一个监听器,SimpleContext类调用LifecycleSupport类的removeLifecycleListener方法:
public void removeLifecycleListener(LifecycleListener listener) { 
   lifecycle.removeLifecycleListener(listener); 
}

要触发一个事件,SimpleContext类调用LifecycleSupport类的fireLifecycleEvent方法:
lifecycle.fireLifecycleEvent(START_EVENT, null);


The Application

本章的应用程序是建立在第五章的应用程序的基础上,它使用了Lifecycle接口和生命周期相关类型。它包含了一个context和两个wrapper,同样也有一个loader和一个mapper。本应用的这些组件都实现了Lifecycle接口,context使用了一个监听器。为了简化这个应用,我们没有使用那两个valve。下面是类图:



注意SimpleContextLifecycleListener类代表SimpleContext类的一个监听器类。SimpleContextValve, SimpleContextMapper和SimpleWrapperValve类同第五章的是一样的。

ex06.pyrmont.core.SimpleContext

本应用的SimpleContext类除了实现了Lifecycle接口,其他和第五章的相似。SimpleContext类使用下面的变量引用一个LifecycleSupport实例:
protected LifecycleSupport lifecycle = new LifecycleSupport(this);

它也用一个叫做started的boolean变量,这个变量表明SimpleContext实例是否启动了。SimpleContext类提供了Lifecycle接口方法的实现。
Listing 6.5: Methods from the Lifecycle interface.   
 
public void addLifecycleListener(LifecycleListener listener) { 
   lifecycle.addLifecycleListener(listener); 
}
public LifecycleListener[] findLifecycleListeners() { 
   return null; 
} 
public void removeLifecycleListener(LifecycleListener listener) { 
   lifecycle.removeLifecycleListener(listener); 
}
public synchronized void start() throws LifecycleException { 
   if (started) 
     throw new LifecycleException("SimpleContext has already started"); 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); 
   started = true;
   try { 
     // Start our subordinate components, if any 
     if ((loader != null) && (loader instanceof Lifecycle)) 
       ((Lifecycle) loader).start(); 
 
     // Start our child containers, if any 
     Container Children[] = findChildren(); 
     for (int i = 0; i < children.length; i++) { 
       if (children[i] instanceof Lifecycle) 
         ((Lifecycle) children[i]).start(); 
     } 
 
     // Start the Valves in our pipeline (including the basic), 
     // if any 
     if (pipeline instanceof Lifecycle) 
       ((Lifecycle) pipeline).start(); 
     // Notify our Interested LifecycleListeners 
     lifecycle.firelifecycleEvent(START_EVENT, null); 
   }
   catch (Exception e) { 
     e.printStackTrace(); 
   } 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); 
} 
 
public void stop() throws LifecycleException { 
   if (!started) 
     throw new LifecycleException("SimpleContext has not been started"); 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); 
   lifecycle.fireLifecycleEvent(STOP_EVENT, null); 
   started = false; 
   try { 
     // Stop the Valves in our pipeline (including the basic), if any 
     if (pipeline instanceof Lifecycle) (
((Lifecycle) pipeline).stop(); 
     } 
     // Stop our child containers, if any 
     Container children[] = findChildren(); 
     for (int i = 0; i < children.length; i++) { 
       if (children[i] instanceof Lifecycle) 
         ((Lifecycle) children[i]).stop();
     } 
     if ((loader != null) && (loader instanceof Lifecycle)) { 
       ((Lifecycle) loader).stop(); 
     } 
   } catch (Exception e) { 
     e.printStackTrace(); 
   } 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); 
} 

注意start方法是怎么来启动所有的像:Loader、Pipeline、Mapper这样的子容器和与它的相关组件,而stop方法又是怎么来停止它们的呢?使用这种机制来启动容器模块的所有组件,你只需要启动在层次结构中最高层的组件(本例中是SimpleContext实例)。要停止它们,你只需要停止同样的这个单独组件。

在SimpleContext中的start方法的开始要通过检查它是否启动,如果这个组件在之前已经启动了,这时将抛一个LifecycleException异常。
if (started) 
   throw new LifecycleException( "SimpleContext has already started");

它然后触发BEFORE_START_EVENT事件。
// Notify our interested LifecycleListeners 
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);

结果,每一个在SimpleContext实例里注册的相关事件监听器将被调用。在这个应用中,一个SimpleContextLifecycleListener类型的监听器注册它的相关事件。

接下来,start方法把started的这个boolean变量设置成true,表明组件被启动了。
  started = true;

然后start方法启动所有组件和它的子容器。当前这里有两个组件,它们都实现了Lifecycle接口。SimpleLoader和SimplePipeline。SimpleContext有两个wrapper作为它的子容器。这两个都是SimpleWrapper类型,它们也都实现了Lifecycle接口。
   try { 
      // Start our subordinate components, if any 
      if ((loader != null) && (loader instanceof Lifecycle)) 
        ((Lifecycle) loader).start(); 
      // Start our child containers, if any 
      Container children[] = findChildren(); 
      for (int i = 0; i < children.length; i++) { 
        if (children[i] instanceof Lifecycle) 
          ((Lifecycle) children[i]).start(); 
      } 
 	  // Start the Valves in our pipeline (including the basic), 
      // if any 
      if (pipeline instanceof Lifecycle) 
        ((Lifecycle) pipeline).start();

当所有组件和子容器都启动后,start方法触发这两事件:START_EVENT和 AFTER_START_EVENT.。
    // Notify our interested LifecycleListeners 
    lifecycle.fireLifecycleEvent(START_EVENT, null); 
    . 
    // Notify our interested LifecycleListeners 
    lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

这个stop方法首先检查这个实例是否启动了,如果没启动,它抛出一个LifecycleException异常。
    if (!started) 
      throw new LifecycleException( "SimpleContext has not been started");

它然后触发BEFORE_STOP_EVENT 和STOP_EVENT这两个事件,并设置started这个boolean变量。
    // Notify our interested LifecycleListeners 
    lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); 
    lifecycle.fireLifecycleEvent(STOP_EVENT, null); 
    started = false;

接下来,stop方法停止它所有相关组件和SimpleContext实例的子容器。
   try { 
    // Stop the Valves in our pipeline (including the basic), if any 
      if (pipeline instanceof Lifecycle) { 
        ((Lifecycle) pipeline).stop(); 
      } 
    // Stop our child containers, if any 
      Container children[] = findChildren(); 
      for (int i = 0; i < children.length; i++) { 
        if (children[i] instanceof Lifecycle) 
          ((Lifecycle) children[i]).stop(); 
      } 
      if ((loader != null) && (loader instanceof Lifecycle)) { 
        ((Lifecycle) loader).stop(); 
      } 
}

最后,触发AFTER_STOP_EVENT事件。
    // Notify our interested LifecycleListeners 
    lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);


ex06.pyrmont.core.SimpleContextLifecycleListener

SimpleContextLifecycleListener类代表一个SimpleContext接口的监听器:
Listing 6.6: The SimpleContextLifecycleListener class   
 
package ex06.pyrmont.core; 
import org.apache.catalina.Context; 
import org.apache.catalina.Lifecycle; 
import org.apache.catalina.LifecycleEvent; 
import org.apache.catalina.LifecycleListener; 
 
public class SimpleContextLifecycleListener implements LifecycleListener { 

public void lifecycleEvent(LifecycleEvent event) { 
     Lifecycle lifecycle = event.getLifecycle();
     System.out.println("SimpleContextLifecycleListener's event " + event.getType().toString()); 
     if (Lifecycle.START_EVENT.equals(event.getType())) { 
       System.out.println("Starting context."); 
     } 
     else if (Lifecycle.STOP_EVENT.equals(event.getType())) { 
       System.out.println("Stopping context."); 
     } 
   } 
} 

SimpleContextLifecycleListener类的lifecycleEvent方法的实现很简单。它只是简单打印被触发的事件。如果它是一个START_EVENT事件,lifecycleEvent方法打印启动上下文(Starting context)。如果事件是一个STOP_EVENT事件它打印停止上下文(Stopping context)。

ex06.pyrmont.core.SimpleLoader

SimpleLoader类除了实现了Lifecycle接口外,其它的和第五章的类似。Lifecycle接口的方法实现就是在控制台打印字符串。更重要的是,通过实现Lifecycle接口,一个SimpleLoader实例可以通过它的相关容器来启动它。
在SimpleLoader的Lifecycle接口的这些方法:
Listing 6.7: The methods from Lifecycle in the SimpleLoader class   
 
public void addLifecycleListener(LifecycleListener listener) { } 
public LifecycleListener[] findLifecycleListeners() { 
   return null; 
} 
public void removeLifecycleListener(LifecycleListener listener) { } 
public synchronized void start() throws LifecycleException { 
   System.out.println("Starting SimpleLoader"); 
} 
public void stop() throws LifecycleException { } 


ex06.pyrmont.core.SimplePipeline

除了实现了Pipeline接口,SimplePipeline类也实现了Lifecycle接口。Lifecycle接口方法的实现是空的,但是现在这个类的实例可以被它相关联的容器来启动。类其它部分跟第五章的SimplePipeline类相同。

ex06.pyrmont.core.SimpleWrapper

这个类和ex05.pyrmont.core.SimpleWrapper类相似。在这个应用,它实现了Lifecycle接口,所以它可以被它的父容器启动。在这个应用程序大多数方法除了start和stop方法,其它方法的实现都为空。
Listing 6.8: The methods from the Lifecycle interface   
 
public void addLifecycleListener(LifecycleListener listener) {  } 
public LifecycleListener[] findLifecycleListeners() { 
   return null; 
} 
public void removeLifecycleListener(LifecycleListener listener) ( } 
public synchronized void start() throws LifecycleException { 
   System.out.println("Starting Wrapper " + name); 
   if (started) 
     throw new LifecycleException("Wrapper already started"); 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); 
   started = true; 
// Start our subordinate components, if any 
   if ((loader != null) && (loader instanceof Lifecycle)) 
     ((Lifecycle) loader).start(); 
   // Start the Valves in our pipeline (including the basic), if any 
   if (pipeline instanceof Lifecycle) 
     ((Lifecycle) pipeline).start(); 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(START_EVENT, null); 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); 
}
public void stop() throws LifecycleException {
   System.out.println("Stopping wrapper " + name); 
   // Shut down our servlet instance (if it has been initialized) 
   try { 
     instance.destroy(); 
   } catch (Throwable t) { 
   } 
   instance = null; 
   if (!started) 
     throw new LifecycleException("Wrapper " + name + " not started"); 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); 
   // Notify our interested LifecycleListeners 
   lifecycle.fireLifecycleEvent(STOP_EVENT, null); 
   started = false;
   // Stop the Valves in our pipeline (including the basic), if any 
   if (pipeline instanceof Lifecycle) { 
     ((Lifecycle) pipeline).stop(); 
   } 
   // Stop our subordinate components, if any 
   if ((loader != null) && (loader instanceof Lifecycle)) { 
     ((Lifecycle) loader).stop(); 
   } 
   // Notify our interested LifecycleListeners 
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); 
}


SimpleWrapper的start方法和SimpleContext类的start方法类似。它启动任何添加到它里面的组件。触发BEFORE_START_EVENT, START_EVENT和AFTER_START_EVENT事件。

SimpleWrapper的stop方法更有趣。打印了一个简单的字符串后,它调用servlet实例的destroy方法。
    System.out.println("Stopping wrapper " + name); 
    // Shut down our servlet instance (if it has been initialized) 
    try { 
      instance.destroy(); 
    } catch (Throwable t) {
} 
 instance = null;

然后,检查wrapper是否启动了,如果没有,它抛出一个LifecycleException异常。
   if (!started) 
      throw new LifecycleException("Wrapper " + name + " not started");

接下来,它触发BEFORE_STOP_EVENT和STOP_EVENT事件。然后设置started这个boolean变量。
    // Notify our interested LifecycleListeners 
    lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); 
    // Notify our interested LifecycleListeners 
    lifecycle.fireLifecycleEvent(STOP_EVENT, null); 
    started = false;

接下来,它停止loader和pipeline相关的组件。在这个应用程序,SimpleWrapper实例没有loader。
    // Stop the Valves in our pipeline (including the basic), if any 
    if (pipeline instanceof Lifecycle) { 
      ((Lifecycle) pipeline).stop(); 
    } 
    // Stop our subordinate components, if any 
    if ((loader != null) && (loader instanceof Lifecycle)) { 
      ((Lifecycle) loader).stop(); 
    } 

最后,它触发 AFTER_STOP_EVENT事件。
    // Notify our interested LifecycleListeners 
    lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); 


总结:这章你知道了怎么与Lifecycle接口工作。这个接口定义了一个组件的生命周期和提供了优雅的方式来发送事件给另一个组件。此外,Lifecycle接口也使得使用一个单独的start/stop来启动和停止在Catalina的所有组件变得可能。
                                              
                                                                       第六章 完
  • 大小: 49.5 KB
1
0
分享到:
评论

相关推荐

    How tomcat works 中文版

    � jsp / servlet 开发人员,想了解 tomcat 内部机制的 coder ; � 想加入 tomcat 开发团队的 coder ; � web 开发人员,但对软件开发很有兴趣的 coder ; � 想要对 tomcat 进行定制的 coder 。 在阅读之前,希望...

    tomcat原理解析书(how-tomcat-works)中文版

    适合读者 1.jsp/servlet 开发人员,想了解 tomcat 内部机制的 coder; 2.想加入 tomcat 开发团队的 coder; 3.web 开发人员,但对软件开发很有兴趣的 coder; 4.想要对 tomcat 进行定制的 coder。

    Bad Programming Practices 101 Become a Better Coder by Learning How (Not) epub

    Bad Programming Practices 101 Become a Better Coder by Learning How (Not) to Program 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索此书

    The Clean Coder

    Prentice Hall | 2011 | ISBN: 0137081073 | 256 pages | PDF | 6 MB Programmers who endure and succeed amidst swirling uncertainty and nonstop pressure share a common attribute: They care deeply about ...

    HDL-Coder详细教程

    HDL-Coder详细教程,有详细例子,源于官方例程,中文教程

    phpcoder.rar

    phpcoder安装包。 直接下载安装即可。

    simulink hdl coder 用户手册pdf

    HDL CODER 的用户手册,学习hdl coder参考用书,详细介绍了用simulink开发fpga的过程

    php coder编辑器

    PHPCoder用于快速开发和调试PHP应用程序,它很容易扩展和定制,完全能够符合开发者的个性要求.PHPCoder是一个非常实用的,功能强大的编程环境,而且它是免费的!

    MediaCoder答题器

    MediaCoder答题器

    Embedded Coder.rar

    texasinstrumentsc2000.mlpkginstall 支持TI的C2000系列工具包,要求MATLAB R2017a及其以上版本。 安装方法:打开matlab,调整路径到mlpkginstall文件所在目录;在current folder窗口里双击mlpkginstall文件即可开始...

    MediaCoder.5755专业破解版

    MediaCoder行业版一款针对VOD及KTV视频点播行业开发的,用于转换和处理带有多音轨内容的视频节目的软件。它具备业界领先的视频编码引擎,在高性能转码的同时保持高画质,并通过丰富的视频滤镜增强画面视觉效果。作为...

    matlab Embedded Coder Getting Started Guide.pdf

    Embedded Coder用于产生嵌入式处理器、目标快速原型板和大规模生产中使用的微处理器的可读的、紧凑的、快速的C和C++代码。Embedded Coder支持附加的MATLAB Coder™和Simulink Coder™配置选项,以及对生成代码的功能...

    MediaCoder使用说明文档

    MediaCoder使用说明文档, mediaCoder usermanual,

    mediacoder专业版

    mediacoder 5685专业版,无普通版的限制

    MediaCoder64位专业破解版

    MediaCoder-Premium-x64 MediaCoder是最早开始使用GPU进行视频编码加速的影音转码软件之一。通过将原本完全依赖CPU的计算工作转移到GPU上进行,H.264和H.265编码所需的时间被大幅缩短。

    range coder.pdf

    range coder, algorithm, compressing.

    coder的建表语句

    coder的建表语句

    AI自动生成SQL语句的开源代码 sqlcoder-main.zip

    开源的AI自动生成SQL语句源代码,这款SQLCoder-70B-Alpha在文本到SQL的转换能力上超越了包括GPT-4在内的所有通用模型,它能更准确地理解你的需求,并生成相应的SQL查询。SQLCoder2和SQLCoder-7B模型已经向公众开放,...

    MatlabCoder使用-Matlab Coder的基本使用.pdf

    MatlabCoder使用-Matlab Coder的基本使用.pdf 微盘资料搬家,自己写的,自己搬家. 请大家支持,点赞!谢谢!

Global site tag (gtag.js) - Google Analytics