欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

举例讲解Java中的多线程编程

程序员文章站 2024-03-06 22:08:50
java创建线程(runnable接口和thread类) 大多数情况,通过实例化一个thread对象来创建一个线程。java定义了两种方式: 实现runnabl...

java创建线程(runnable接口和thread类)
大多数情况,通过实例化一个thread对象来创建一个线程。java定义了两种方式:

  1. 实现runnable 接口;
  2. 可以继承thread类。

下面的依次介绍了每一种方式。
实现runnable接口

创建线程的最简单的方法就是创建一个实现runnable 接口的类。runnable抽象了一个执行代码单元。你可以通过实现runnable接口的方法创建每一个对象的线程。为实现runnable 接口,一个类仅需实现一个run()的简单方法,该方法声明如下:

  public void run( )


在run()中可以定义代码来构建新的线程。理解下面内容是至关重要的:run()方法能够像主线程那样调用其他方法,引用其他类,声明变量。仅有的不同是run()在程序中确立另一个并发的线程执行入口。当run()返回时,该线程结束。

在你已经创建了实现runnable接口的类以后,你要在类内部实例化一个thread类的对象。thread 类定义了好几种构造函数。我们会用到的如下:

  thread(runnable threadob, string threadname)


该构造函数中,threadob是一个实现runnable接口类的实例。这定义了线程执行的起点。新线程的名称由threadname定义。

建立新的线程后,它并不运行直到调用了它的start()方法,该方法在thread 类中定义。本质上,start() 执行的是一个对run()的调用。 start()方法声明如下:

  void start( )

下面的例子是创建一个新的线程并启动它运行:

// create a second thread.
class newthread implements runnable {
  thread t;
  newthread() {
    // create a new, second thread
    t = new thread(this, "demo thread");
    system.out.println("child thread: " + t);
    t.start(); // start the thread
  }

  // this is the entry point for the second thread.
  public void run() {
    try {
      for(int i = 5; i > 0; i--) {
        system.out.println("child thread: " + i);
        thread.sleep(500);
      }
    } catch (interruptedexception e) {
      system.out.println("child interrupted.");
    }
    system.out.println("exiting child thread.");
  }
}

class threaddemo {
  public static void main(string args[]) {
    new newthread(); // create a new thread
    try {
      for(int i = 5; i > 0; i--) {
        system.out.println("main thread: " + i);
        thread.sleep(1000);
      }
    } catch (interruptedexception e) {
      system.out.println("main thread interrupted.");
    }
    system.out.println("main thread exiting.");
  }
}

在newthread 构造函数中,新的thread对象由下面的语句创建::

  t = new thread(this, "demo thread");


通过前面的语句this 表明在this对象中你想要新的线程调用run()方法。然后,start() 被调用,以run()方法为开始启动了线程的执行。这使子线程for 循环开始执行。调用start()之后,newthread 的构造函数返回到main()。当主线程被恢复,它到达for 循环。两个线程继续运行,共享cpu,直到它们的循环结束。该程序的输出如下:

child thread: thread[demo thread,5,main]
main thread: 5
child thread: 5
child thread: 4
main thread: 4
child thread: 3
child thread: 2
main thread: 3
child thread: 1
exiting child thread.
main thread: 2
main thread: 1
main thread exiting.

如前面提到的,在多线程程序中,通常主线程必须是结束运行的最后一个线程。实际上,一些老的jvm,如果主线程先于子线程结束,java的运行时间系统就可能“挂起”。前述程序保证了主线程最后结束,因为主线程沉睡周期1000毫秒,而子线程仅为500毫秒。这就使子线程在主线程结束之前先结束。简而言之,你将看到等待线程结束的更好途径。
扩展thread

创建线程的另一个途径是创建一个新类来扩展thread类,然后创建该类的实例。当一个类继承thread时,它必须重载run()方法,这个run()方法是新线程的入口。它也必须调用start()方法去启动新线程执行。下面用扩展thread类重写前面的程序:

// create a second thread by extending thread
class newthread extends thread {
  newthread() {
    // create a new, second thread
    super("demo thread");
    system.out.println("child thread: " + this);
    start(); // start the thread
  }

  // this is the entry point for the second thread.
  public void run() {
    try {
      for(int i = 5; i > 0; i--) {
        system.out.println("child thread: " + i);
        thread.sleep(500);
      }
    } catch (interruptedexception e) {
      system.out.println("child interrupted.");
    }
    system.out.println("exiting child thread.");
  }
}

class extendthread {
  public static void main(string args[]) {
    new newthread(); // create a new thread
    try {
      for(int i = 5; i > 0; i--) {
        system.out.println("main thread: " + i);
        thread.sleep(1000);
      }
    } catch (interruptedexception e) {
      system.out.println("main thread interrupted.");
    }
    system.out.println("main thread exiting.");
  }
}

该程序生成和前述版本相同的输出。子线程是由实例化newthread对象生成的,该对象从thread类派生。注意newthread 中super()的调用。该方法调用了下列形式的thread构造函数:

  public thread(string threadname)


这里,threadname指定线程名称。
选择合适方法

到这里,你一定会奇怪为什么java有两种创建子线程的方法,哪一种更好呢。所有的问题都归于一点。thread类定义了多种方法可以被派生类重载。对于所有的方法,惟一的必须被重载的是run()方法。这当然是实现runnable接口所需的同样的方法。很多java程序员认为类仅在它们被加强或修改时应该被扩展。因此,如果你不重载thread的其他方法时,最好只实现runnable 接口。这当然由你决定。然而,在本章的其他部分,我们应用实现runnable接口的类来创建线程。