Java创建线程的两种方法
大多数情况,通过实例化一个Thread对象来创建一个线程。Java定义了两种方式:
- 实现Runnable 接口;
- 可以继承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接口的类来创建线程。
转自微学苑(http://www.weixueyuan.net/view/6027.html)
Java创建线程的两种方法的更多相关文章
- Java 创建线程的两种方法
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- java创建线程的四种方法
第一种: 通过继承Thread类创建线程 第二种: 通过实现Runnable接口创建线程 这两种早已烂记于心,这里就不作过多的介绍, 主要介绍其源码 Thread类 implements Runna ...
- java创建线程的三种方法
这里不会贴代码,只是将创建线程的三种方法做个笼统的介绍,再根据源码添加上自己的分析. 通过三种方法可以创建java线程: 1.继承Thread类. 2.实现Runnable接口. 3.实现Callab ...
- Java创建线程的两个方法
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- java创建线程的两种方式及源码解析
创建线程的方式有很多种,下面我们就最基本的两种方式进行说明.主要先介绍使用方式,再从源码角度进行解析. 继承Thread类的方式 实现Runnable接口的方式 这两种方式是最基本的创建线程的方式,其 ...
- 进程和创建线程的两种方法(threading.Thread)
进程 如QQ 要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,内存的管理, 网络接口的调用等,进程就是各种资源管理的集合 线程:是操作系统最小的调度单位,是一串指令的结合 进程 要操作 ...
- Java线程(一)——创建线程的两种方法
Thread 和 Runnable Java程序是通过线程执行的,线程在程序中具有独立的执行路径.当多条线程执行时,它们之间的路径可以不同,例如,一条线程可能在执行switch的一个case语句,另一 ...
- 区分JAVA创建线程的几种方法
1. start()和run() 通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行.然后 通过此Thread类调用方法run()来完成其运行操 ...
- Java 创建线程的3种方法及各自优势
1. 继承 Thread 类,然后调用 start 方法. class MyThread extends Thread { //重写run方法,线程运行后,跑的就是run方法 public void ...
随机推荐
- 洛谷P1714切蛋糕
题目 该题目就是求这n个数的前缀和所组成的数组的所有子区间的左端点和右端点相差不超过m,且他们的前缀和差最大,求出这个最大值即可. 而朴素算法肯定会T,而我们发现如果前缀和最大的话,则前缀和的值一定是 ...
- 原创:ThreadPoolExecutor线程池深入解读(一)----原理+应用
本文档,适合于对多线程有一定基础的开发人员.对多线程的一些基础性的解读,请参考<java并发编程>的前5章. 对于源代码的解读,本人认为可读可不读.如果你想成为一位顶级的程序员,那就培养自 ...
- 9.本地线程(ThreadLoca)
ThreadLoca 提高一个线程的局部变量,访问某个线程都有自己的局部变量,当使用ThreadLoca为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立的改变自己的副本,二不会影响到 ...
- 系统假死——系统频繁Full gc问题分析
主要可能的原因: 1,eden区太小,eden和survivor默认比例是8:12,old区太小,新生代和老年代的比例也可以调节的.3,是否程序会分配很多短期存活的大对象,程序本身是否有问题? 进入老 ...
- JVM 类加载器的双亲委托机制
1.类加载器的层次结构 在双亲委托机制中,各个加载器按照父子关系形成了树形结构(逻辑意义),除了根加载器之外,其余的类加载器都有且只有一个父加载器. public class MyTest13 { p ...
- Win10 剪贴板 快捷键是什么?
使用基于云的剪贴板从一台电脑上复制图像和文本并粘贴到另一台电脑上.你不仅可以从剪贴板历史记录中粘贴,还可以固定你发现自己经常使用的项目. 若要随时访问剪贴板历史记录,请按 Windows 徽标键 ...
- 【Java.Regex】用正则表达式查找Java源文件中的注释
代码: package regex; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.I ...
- Eclipse创建的Java Web项目,如何启用外置浏览器访问jsp或者html页面
当我们用Eclipse创建了一个Java Web项目,想访问一个jsp或者html页面时,通常会在目标页面(以jsp为例)上点击鼠标右键,选择[Run As]——>[Run on Server] ...
- Python 3.8.0 final¶ Release date: 2019-10-14
https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-0 Core and Builtins bpo-38469: Fixed ...
- python+opencv抠图并旋转(根据坐标抠图)
import cv2 import numpy as np def subimage(image, center, theta, width, height): theta *= np.pi / 18 ...