为了实现在同一时间运行多个任务,Java引入了多线程概念。在Java中可以通过方便、快捷的方式启动多线程模式。多线程常被应用在符合并发机制的程序中,例如网络程序等。
一、线程简介
每个独立运行执行的程序都被称为进程,比如正在运行的QQ是一个进程、正在进行的IE浏览器也是一个进程,每个进程都可以包含多个线程。系统可以分配给每个进程一段使用CPU的时间,CPU在这段时间执行某个进程(同理,同一个进程中的每个线程也可以得到一小段执行时间,这样一个进程就可以具有多个并发执行的线程),由于CPU转换较快,所以使得每个进程好像是被同时执行一样。
二、实现线程的三种方式
1、继承Thread类
Thread类是java.lang包中的一个类,Thread类的对象用来代表线程,通过继承Thread类创建、启动并执行一个线程的步骤如下:
(1)创建一个继承Thread类的子类;
(2)覆写Thread类的run()方法;
(3)创建线程类的一个对象;
(4)通过线程类的对象调用start()方法启动线程(启动后悔自动调用覆写的run()方法执行线程);
代码如下:
public class ThreadCreate {
public static void main(String[] args) {
new MyThread1().start();
}
}
//继承Thread类
class MyThread1 extends Thread{
@Override
public void run() {
System.out.println("MyThread1");
}
}
Java虚拟机调用Java程序的main方法时,就启动了主线程。如果想启动其他线程,那么需要通过线程类调用start()方法来实现,代码如下:
public static void main(String[] args) {
Thread thread = new Thread();
thread.start();
}
注意:如果start()方法调用一个已经启动的线程,系统将抛出异常。
2、实现Runnable接口
如果当前类不仅要继承其他类(非Thread类),还要实现多线程,这个时候就可以用Runnable接口来创建Thread类对象了。
从Java API中可以发现,Thread类已经实现了Runnable接口,Thread类的run()方法正是Runnable接口中的run()方法的具体实现。
实现Runnable接口的程序会创建一个Thread对象,并将Runnable和Thread对象相关联。
使用Runnable接口启动线程步骤如下:
(1)创建一个实现Runnable接口的类;
(2)实现run方法(在方法当中写多线程需要执行的代码);
(3)将实现Runnable接口的类以参数形式构造Thread类;
(4)最后使用Thread对象调用start()方法启动;
代码如下:
public class ThreadCreate {
public static void main(String[] args) {
new Thread(new MyThread2()).start();
}
}
//实现Runnable接口
class MyThread2 implements Runnable{
@Override
public void run() {
System.out.println("MyThread2");
}
}
3、实现Callable接口
和Runnable接口不一样,Callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。
call()方法可以有返回值
使用Callable接口启动线程步骤如下:
(1)创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例(从java8开始可以直接使用Lambda表达式创建Callable对象)。
(2)使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值
(3)使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口)
(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值
代码如下:
public class ThreadCreate {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread3());
new Thread(futureTask).start();
Integer integer = futureTask.get();
System.out.println(integer);
}
}
//实现Runnable接口
class MyThread3 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("MyThread3");
return 100;
}
}