class="MsoNormal">? ? ? ? 传统的程序设计语言同一时刻只能执行单任务操作,效率非常低,如果网络程序在接收数据时发生阻塞,只能等到程序接收数据之后才能继续运行。随着 Internet 的飞速发展,这种单任务运行的状况越来越不被接受。如果网络接收数据阻塞,后台服务程序就会一直处于等待状态而不能继续任何操作。这种阻塞情况经常发生,这时的 CPU资源完全处于闲置状态。
??? ? ? ?多线程实现后台服务程序可以同时处理多个任务,并不发生阻塞现象。多线程是 Java 语言的一个很重要的特征。多线程程序设计最大的特点就是能够提高程序执行效率和处理速度。Java 程序可同时并行运行多个相对独立的线程。例如创建一个线程来接收数据,另一个线程发送数据,既使发送线程在接收数据时被阻塞,接受数据线程仍然可以运行。?线程(Thread)是控制线程(Thread of Control)的缩写,它是具有一定顺序的指令序列(即所编写的程序代码)、存放方法中定义局部变量的栈和一些共享数据。线程是相互独立的,每个方法的局部变量和其他线程的局部变量是分开的,因此,任何线程都不能访问除自身之外的其他线程的局部变量。如果两个线程同时访问同一个方法,那每个线程将各自得到此方法的一个拷贝。?
? ? ? ?Java 提供的多线程机制使一个程序可同时执行多个任务。线程有时也被称为小进程,它是从一个大进程里分离出来的小的独立的线程。由于实现了多线程技术,Java 显得更健壮。多线程带来的好处是更好的交互性能和实时控制性能。多线程是强大而灵巧的编程工具,但要用好它却不是件容易的事。在多线程编程中,每个线程都通过代码实现线程的行为,并将数据供给代码操作。编码和数据有时是相当独立的,可分别向线程提供。多个线程可以同时处理同一代码和同一数据,不同的线程也可以处理各自不同的编码和数据。?
? ? ? ?Java程序都是声明一个公共类,并在类内实现一个 main 方法。事实上,这些程序就是一个单线程程序。当它执行完main 方法的程序后,线程正好退出,程序同时结束运行。
?
public class OnlyThread {
public static void main(String args[]) {
run(); // 调用静态run()方法
}
/**
* 实现run()方法
*/
public static void run() {
// 循环计算输出的*数目
for (int count = 1, row = 1; row < 10; row++, count++) {
for (int i = 0; i < count; i++) { // 循环输出指定的count数目的*
System.out.print('*');
}
System.out.println();
}
}
}
?
?
??这只是建立了一个单一线程并执行的普通小程序,并没有涉及到多线程的概念。
? ? ??在 Java程序中,有两种方法创建线程:
? ? ? ? 一是对 Thread 类进行派生并覆盖 run方法;
? ? ? ? 二是通过实现 runnable接口创建。?
? ? ?在程序中创建新的线程的方法之一是继承 Thread 类,并通过 Thread子类声明线程对象。继承Thread 类并覆盖 Thread类的 run 方法完成线程类的声明,通过new创建派生线程类的线程对象。run 中的代码实现了线程的行为。?
?
? ? ??java.lang.Thread 类是一个通用的线程类,由于默认情况下 run 方法是空的,直接通过 Thread类实例化的线程对象不能完成任何事,所以可以通过派生 Thread 类,并用具体程序代码覆盖Thread 类中的 run 方法,实现具有各种不同功能的线程类。
?
? ? ??1)?Thread 创建线程步骤:?
?
? ? ?(1)创建一个新的线程类,继承 Thread 类并覆盖 Thread 类的 run()方法。?
?
class ThreadType extends Thread{
public void run(){
……
}
}
?
?
(2)创建一个线程类的对象,创建方法与一般对象的创建相同,使用关键字new完成。
?
ThreadType tt = new ThreadType();
?(3)启动新线程对象,调用 start()方法。
?
?
tt.start();
?(4)线程自己调用 run()方法。
?
?
void run();
?
?
?
??2)?Thread创建一个线程
?
? ? ?
class ThreadDemo1 extends Thread {
ThreadDemo1() {
}
// 声明ThreadDemo1带参数的构造方法
ThreadDemo1(String szName) {
super(szName);
}
// 重载run函数
public void run() {
for (int count = 1, row = 1; row < 10; row++, count++) {
for (int i = 0; i < count; i++) {// 循环输出指定的count数目的*
System.out.print('*');
}
System.out.println();
}
}
public static void main(String argv[]) {
ThreadDemo1 td = new ThreadDemo1(); // 创建,并初始化ThreadDemo1类型对象td
td.start(); // 调用start()方法执行一个新的线程
}
}
?
?
?
??OnlyThread.java程序与程序ThreadDemo1.java表面上看运行结果相同,但是仔细对照会发现,程序OnlyThread.java中对 run方法的调用在程序ThreadDemo1.java中变成了对 start 方法的调用,并且程序ThreadDemo1.java确派生 Thread类,创建新的线程类。?
?
?3)?Thread创建多个线程
//文件:程序10.3 ThreadDemo2.java ? 描述:产生三个新的线程?
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
public class ThreadDemo2 extends Thread {
// 声明无参数,空构造方法
ThreadDemo2() {
}
// 声明带有字符串参数的构造方法
ThreadDemo2(String szName) {
super(szName); // 调用父类的构造方法
}
// 重载run函数
public void run() {
for (int count = 1, row = 1; row < 10; row++, count++) {
for (int i = 0; i < count; i++) {// 循环输出指定的count数目的*
System.out.print('*');
}
System.out.println();
}
}
public static void main(String argv[]) {
ThreadDemo2 td1 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td1
ThreadDemo2 td2 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td2
ThreadDemo2 td3 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td3
td1.start(); // 启动线程td1
td2.start(); // 启动线程td2
td3.start(); // 启动线程td3
}
}
?创建了 3 个线程 td1、td2、td3,它们分别执行自己的 run方法。在实际中运行的结果并不是想要的直角三角形,而是一些乱七八糟的 “*” 行,长短并没有一定的规律,这是因为线程并没有按照程序中调用的顺序来执行,而是产生了多个线程赛跑现象。?运行结果:
?
?注意:Java线程并不能按调用顺序执行,而是并行执行的单独代码。如果要想得到完整的直角三角形,需要在执行一个线程之前,判断程序前面的线程是否终止,如果已经终止,再来调用该线程。
?
?
?
? ? ? ? 通过实现 Runnable 接口的方法是创建线程类的第二种方法。利用实现 Runnable 接口来创建线程的方法可以解决 Java 语言不支持的多重继承问题。 ? ? ? ? ? ? ? ?Runnable 接口提供了 run()方法的原型,因此创建新的线程类时,只要实现此接口,即只要特定的程序代码实现Runnable接口中的 run()方法,就可完成新线程类的运行。
?
? ? ??扩展Thread类创建线程的方式,适合编写简单的应用程序代码,而实现Runnable接口创建线程,能够避免Java单继承的局限,适合同一代码的多线程处理同一资源的情况,代码具有良好的一致性,是更符合面向对象思想的设计方式。
?
? ? ?1)?Runnable 创建线程步骤?
? ?(1)创建一个实现 Runnable 接口的类,并且在这个类中重写 run 方法。
?
?
class ThreadType implements Runnable{
public void run(){
……
}
}
?(2)使用关键字 new新建一个 ThreadType 的实例。
Runnable rb = new ThreadType ();
?(3)通过 Runnable 的实例创建一个线程对象,在创建线程对象时,调用的构造函数是new Thread(ThreadType),它用 ThreadType 中实现的 run()方法作为新线程对象的 run()方法。?
?
Thread td = new Thread(rb);
?(4)通过调用 ThreadType 对象的 start()方法启动线程运行。?
td.start();
??2) Runnable 创建线程
?
?
class ThreadDemo3 implements Runnable {
// 重载run函数
public void run() {
for (int count = 1, row = 1; row < 10; row++, count++){ // 循环计算输出的*数目
for (int i = 0; i < count; i++){ // 循环输出指定的count数目的*
System.out.print('*');
}
System.out.println();
}
}
public static void main(String argv[]) {
Runnable rb = new ThreadDemo3(); // 创建,并初始化ThreadDemo3对象rb
Thread td = new Thread(rb); // 通过Thread创建线程
td.start(); // 启动线程td
}
}
?
?