最简洁完整的Java高级教程之二(数据结构、集合、网络编程、多线程)

来源:互联网 发布:电脑发短信软件 编辑:程序博客网 时间:2024/03/29 05:10
                               Java高级教程(二)
6.Java 发送邮件
     使用Java应用程序发送 E-mail 十分简单,但是首先你应该在你的机器上安装 JavaMail API 和Java Activation Framework (JAF) 。
  • 您可以从 Java 网站下载最新版本的 JavaMail,打开网页右侧有个 Downloads 链接,点击它下载。
  • 您可以从 Java 网站下载最新版本的 JAF(版本 1.1.1)。
     下载并解压缩这些文件,在新创建的顶层目录中,您会发现这两个应用程序的一些 jar 文件。您需要把 mail.jar 和 activation.jar 文件添加到您的 CLASSPATH 中。
如果你使用第三方邮件服务器如QQ的SMTP服务器,可查看文章用户认证完整的实例。
     6.1发送一封简单的 E-mail
     
     下面是对于参数的描述:
  • type:要被设置为 TO, CC 或者 BCC,这里 CC 代表抄送、BCC 代表秘密抄送。举例:Message.RecipientType.TO
  • addresses: 这是 email ID 的数组。在指定电子邮件 ID 时,你将需要使用 InternetAddress() 方法。
     6.2发送一封 HTML E-mail
     
     6.3发送带有附件的 E-mail
     
     6.4用户认证部分
          如果需要提供用户名和密码给e-mail服务器来达到用户认证的目的,你可以通过如下设置来完成:
props.put("mail.smtp.auth", "true");
props.setProperty("mail.user", "myuser");
props.setProperty("mail.password", "mypwd");
     

7.Java 多线程编程
     Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径。多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。
     这里定义和线程相关的另一个术语 - 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有的非守候线程都结束运行后才能结束。
     7.1一个线程的生命周期
          线程是一个动态执行的过程,它也有一个从产生到死亡的过程。
     
  • 新建状态:
          使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
  • 就绪状态:
          当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
  • 运行状态:
          如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
  • 阻塞状态:
          如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
    • 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
    • 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
    • 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
  • 死亡状态:
          一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
     7.2线程的优先级
          每一个 Java 线程都有一个优先级,这样有助于操作系统确定线程的调度顺序。Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )。默认情况下,每一个线程都会分配一个优先级 NORM_PRIORITY(5)。具有较高优先级的线程对程序更重要,并且应该在低优先级的线程之前分配处理器资源。但是,线程优先级不能保证线程执行的顺序,而且非常依赖于平台。
     7.3创建一个线程
          Java 提供了三种创建线程的方法:
  • 通过实现 Runnable 接口;
  • 通过继承 Thread 类本身;
  • 通过 Callable 和 Future 创建线程。
     7.4通过实现 Runnable 接口来创建线程
          创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类。为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下:
public void run()
          你可以重写该方法,重要的是理解的 run() 可以调用其他方法,使用其他类,并声明变量,就像主线程一样。在创建一个实现 Runnable 接口的类之后,你可以在类中实例化一个线程对象。Thread 定义了几个构造方法,下面的这个是我们经常使用的:
Thread(Runnable threadOb,String threadName);
          这里,threadOb 是一个实现 Runnable 接口的类的实例,并且 threadName 指定新线程的名字。新线程创建之后,你调用它的 start() 方法它才会运行。
void start();
     
     7.5通过继承Thread来创建线程
          创建一个线程的第二种方法是创建一个新的类,该类继承 Thread 类,然后创建一个该类的实例。继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable 接口的一个实例。
     
     
     
     
     7.6通过 Callable 和 Future 创建线程
  • 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
  • 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
  • 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
  • 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
     7.7线程的几个主要概念,在多线程编程时,你需要了解以下几个概念:
  • 线程同步
  • 线程间通信
  • 线程死锁
  • 线程控制:挂起、停止和恢复

8.Java Applet 基础
     Applet 是一种 Java 程序。它一般运行在支持 Java 的 Web 浏览器内。因为它有完整的 Java API支持,所以Applet 是一个全功能的 Java 应用程序。
     如下所示是独立的 Java 应用程序和 applet 程序之间重要的不同:
  • Java 中 Applet 类继承了 java.applet.Applet 类。
  • Applet 类没有定义 main(),所以一个 Applet 程序不会调用 main() 方法。
  • Applet 被设计为嵌入在一个 HTML 页面。
  • 当用户浏览包含 Applet 的 HTML 页面,Applet 的代码就被下载到用户的机器上。
  • 要查看一个 Applet 需要 JVM。 JVM 可以是 Web 浏览器的一个插件,或一个独立的运行时环境。
  • 用户机器上的 JVM 创建一个 Applet 类的实例,并调用 Applet 生命周期过程中的各种方法。
  • Applet 有 Web 浏览器强制执行的严格的安全规则,Applet 的安全机制被称为沙箱安全。
  • Applet 需要的其他类可以用 Java 归档(JAR)文件的形式下载下来。
     8.1Applet的生命周期
          Applet 类中的四个方法给你提供了一个框架,你可以在该框架上开发小程序:
  • init: 该方法的目的是为你的 Applet 提供所需的任何初始化。在 Applet 标记内的 param 标签被处理后调用该方法。
  • start: 浏览器调用 init 方法后,该方法被自动调用。每当用户从其他页面返回到包含 Applet 的页面时,则调用该方法。
  • stop: 当用户从包含 Applet 的页面移除的时候,该方法自动被调用。因此,可以在相同的 Applet 中反复调用该方法。
  • destroy: 此方法仅当浏览器正常关闭时调用。因为 Applet 只有在 HTML 网页上有效,所以你不应该在用户离开包含 Applet 的页面后遗漏任何资源。
  • paint: 该方法在 start() 方法之后立即被调用,或者在 Applet 需要重绘在浏览器的时候调用。paint() 方法实际上继承于 java.awt。
     8.2"Hello, World" Applet:
          下面是一个简单的 Applet 程序 HelloWorldApplet.java:
     
          没有这些 import 语句,Java 编译器就识别不了 Applet 和 Graphics 类。
     8.3Applet 类
          每一个 Applet 都是 java.applet.Applet 类的子类,基础的 Applet 类提供了供衍生类调用的方法,以此来得到浏览器上下文的信息和服务。这些方法做了如下事情:
  • 得到 Applet 的参数
  • 得到包含 Applet 的 HTML 文件的网络位置
  • 得到 Applet 类目录的网络位置
  • 打印浏览器的状态信息
  • 获取一张图片
  • 获取一个音频片段
  • 播放一个音频片段
  • 调整此 Applet 的大小
          除此之外,Applet 类还提供了一个接口,该接口供 Viewer 或浏览器来获取 Applet 的信息,并且来控制 Applet 的执行。Viewer 可能是:
  • 请求 Applet 作者、版本和版权的信息
  • 请求 Applet 识别的参数的描述
  • 初始化 Applet
  • 销毁 Applet
  • 开始执行 Applet
  • 结束执行 Applet
     8.4Applet 的调用
          <applet> 标签是在HTML文件中嵌入 Applet 的基础。以下是一个调用"Hello World"applet的例子;
     
          <applet> 标签的属性指定了要运行的 Applet 类。width 和 height 用来指定 Applet 运行面板的初始大小。Applet 必须使用 </applet> 标签来关闭。如果 Applet 接受参数,那么参数的值需要在 <param> 标签里添加,该标签位于 <applet> 和 </applet> 之间。浏览器忽略了 applet 标签之间的文本和其他标签。不支持 Java 的浏览器不能执行 <applet> 和 </applet>。因此,在标签之间显示并且和 applet 没有关系的任何东西,在不支持的 Java 的浏览器里是可见的。Viewer 或者浏览器在文档的位置寻找编译过的 Java 代码,要指定文档的路径,得使用 <applet> 标签的 codebase 属性指定。
<applet codebase="http://amrood.com/applets"
code="HelloWorldApplet.class" width="320" height="120">
          如果 Applet 所在一个包中而不是默认包,那么所在的包必须在 code 属性里指定,例如:
<applet code="mypackage.subpackage.TestApplet.class"
  width="320" height="120">
     8.5获得applet参数
          下面的例子演示了如何使用一个 Applet 响应来设置文件中指定的参数。该 Applet 显示了一个黑色棋盘图案和第二种颜色。第二种颜色和每一列的大小通过文档中的 Applet 的参数指定。CheckerApplet 在 init() 方法里得到它的参数。也可以在 paint() 方法里得到它的参数。然而,在 Applet 开始得到值并保存了设置,而不是每一次刷新的时候都得到值,这样是很方便,并且高效的。Applet viewer 或者浏览器在 Applet 每次运行的时候调用 init() 方法。在加载 Applet 之后,Viewer 立即调用 init() 方法(Applet.init()什么也没做),重写该方法的默认实现,添加一些自定义的初始化代码。Applet.getParameter() 方法通过给出参数名称得到参数值。如果得到的值是数字或者其他非字符数据,那么必须解析为字符串类型。
     
          该 Applet 调用 parseSquareSize(),来解析 squareSize 参数。parseSquareSize() 调用了库方法 Integer. parseInt() 该方法将一个字符串解析为一个整数,当参数无效的时候,Integer.parseInt() 抛出异常。因此,parseSquareSize() 方法也是捕获异常的,并不允许 Applet 接受无效的输入。Applet 调用 parseColor()方法将颜色参数解析为一个 Color 值。parseColor() 方法做了一系列字符串的比较,来匹配参数的值和预定义颜色的名字。你需要实现这些方法来使 Applet 工作。
     8.6指定 applet 参数
          如下的例子是一个HTML文件,其中嵌入了 CheckerApplet 类。HTML文件通过使用 <param> 标签的方法给 applet 指定了两个参数。
     
     8.7应用程序转换成 Applet
          将图形化的 Java 应用程序(是指,使用AWT的应用程序和使用 java 程序启动器启动的程序)转换成嵌入在web页面里的applet是很简单的。下面是将应用程序转换成 Applet 的几个步骤:
  • 编写一个 HTML 页面,该页面带有能加载 applet 代码的标签。
  • 编写一个 JApplet 类的子类,将该类设置为 public。否则,Applet 不能被加载。
  • 消除应用程序的 main()方法。不要为应用程序构造框架窗口,因为你的应用程序要显示在浏览器中。
  • 将应用程序中框架窗口的构造方法里的初始化代码移到 Applet 的 init() 方法中,你不必显示的构造 Applet 对象,浏览器将通过调用 init() 方法来实例化一个对象。
  • 移除对 setSize() 方法的调用,对于 Applet 来讲,大小已经通过 HTML 文件里的 width 和 height 参数设定好了。
  • 移除对 setDefaultCloseOperation() 方法的调用。Applet 不能被关闭,它随着浏览器的退出而终止。
  • 如果应用程序调用了 setTitle() 方法,消除对该方法的调用。applet 不能有标题栏。(当然你可以给通过 html 的 title 标签给网页自身命名)
  • 不要调用 setVisible(true),Applet 是自动显示的。
     8.8事件处理
          Applet 类从 Container 类继承了许多事件处理方法。Container 类定义了几个方法,例如:processKeyEvent() 和processMouseEvent(),用来处理特别类型的事件,还有一个捕获所有事件的方法叫做 processEvent。为了响应一个事件,Applet 必须重写合适的事件处理方法。
     
          最开始运行,Applet 显示 "initializing the applet. Starting the applet.",然后你一点击矩形框,就会显示 "mouse clicked" 。
     8.9显示图片
          Applet 能显示 GIF,JPEG,BMP 等其他格式的图片。为了在 Applet 中显示图片,你需要使用 java.awt.Graphics 类的drawImage()方法。
     
     8.10播放音频
          Applet 能通过使用 java.applet 包中的 AudioClip 接口播放音频。AudioClip 接口定义了三个方法:
  • public void play(): 从一开始播放音频片段一次。
  • public void loop(): 循环播放音频片段
  • public void stop(): 停止播放音频片段
          为了得到 AudioClip 对象,你必须调用 Applet 类的 getAudioClip() 方法。无论 URL 指向的是否是一个真实的音频文件,该方法都会立即返回结果。直到要播放音频文件时,该文件才会下载下来。
     

0 0
原创粉丝点击