进行并发程序设计,首先必须对多线程有足够的了解。在JAVA语言中,多线程通常通过Thread类和Runnable接口来实现。本文就总结它们的使用。
1、Thread类
在JAVA APIDOCS中,Thread类有这样一段话:
线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:
调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。
非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。
创建线程时,必须使用该类。该类封装了线程的行为。
2、Runnable接口
API中的解释是:
Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为 run 的无参数方法。
设计该接口的目的是为希望在活动时执行代码的对象提供一个公共协议。例如,Thread 类实现了 Runnable。激活的意思是说某个线程已启动并且尚未停止。
此外,Runnable 为非 Thread 子类的类提供了一种激活方式。通过实例化某个 Thread 实例并将自身作为运行目标,就可以运行实现 Runnable 的类而无需创建 Thread 的子类。大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类创建子类。
这段解释已经将Runnable的作用说的十分清楚了。
3、创建、启动线程及注意事项
(1)JAVA中创建线程有两种方式:
1)通过继承Thread类,通常应该重写其run方法,将线程运行的逻辑放在其中。因为Thread中的run方法是一个空实现。
2)通过实现Runnable接口,然后通过实例化一个Thread实例并将自身作为运行目标。
那么在使用中,应该使用那种方式呢?当然使用哪种方式都行,然而在Runnable接口API文档中已经详细地说明该如何选择这两种方式:大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类(Thread)创建子类。
在第二种方式中,经常会使用内部类的方式来使用。
(2)启动线程
因为run方法是不能显示调用的,启动一个线程不是调用run方法,而是调用Thread类的start方法。
启动线程大概有以下五种方式:(来自温绍锦(昵称:温少)://www.cnblogs.com/jobs/)
当然提供名称并非必须的,因为如果不指定名称,系统会自动生成一个名称,自动生成的名称的形式为 "Thread-"+n,其中的 n 为整数。
4、重要方法的使用与说明
Thread类中,有些方法会经常使用到,除了run、start等方法外,sleep、join、interrupt、isInterrupted、interrupted(静态方法)以及从Object类继承下来的wait、notify、notifyAll等方法也经常被使用。对于sleep、join和wait,需要注意的是什么时候抛出InterruptedException异常以及如何处理该异常,这些都与中断(interrupt)有关,将在下一篇文章(第二篇 多线程的使用——中断处理)中与其他几个与中断有关的方法一起介绍。
另外需要注意的是,resume、stop、suspend等方法已经被废除,不建议使用,建议使用信号量(共享变量)或interrupt方法来代替stop方法等。详细参见API文档,Thread类相应的方法说明。http://gceclub.sun.com.cn/Java_Docs/jdk6/html/zh_CN/api/index.html
另外currentThread方法通常用于在run方法中获取当前线程对象(即执行该run方法的线程对象)。