您的位置:首页 > 编程语言 > Java开发

Java多线程实现方式

2015-12-31 00:00 525 查看
摘要: Java多线程实现方式有三种:继承thread类,实现Runnable接口,使用ExecutorService。其中前两种方式线程执行完后都没有返回值,只有最后一种带有返回值。

1、继承Thread类实现多线程
Thread本质上是实现了Runnable接口的一个实例,它代表一个线程的实例。这种方式通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。

public class MyThread extends Thread {
  public void run() {
   System.out.println("MyThread.run()");
  }
}
//启动MyThread
MyThread myThread = new MyThread();
myThread.start();


2、实现Runnable接口方式实现多线程
如果自己的类已经extends另一个类,就无法直接extends Thread,此时,必须实现一个Runnable接口,实现run()方法。为了启动MyThread,需要首先实例化一个Thread,并传入自己的MyThread实例,如下:

public class MyThread extends OtherClass implements Runnable {
  public void run() {
   System.out.println("MyThread.run()");
  }
}
//启动myThread
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();


3、使用ExecutorService实现有返回结果的多线程

可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。执行Callable任务后,可以获取一个Future 的对象,在该对象上调用get就可以获取到Callable任务返回的Object了,再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了

import java.util.concurrent.*;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;

/**
* 有返回值的线程
*/
@SuppressWarnings("unchecked")
public class Test {
public static void main(String[] args) throws ExecutionException,
InterruptedException {
System.out.println("----程序开始运行----");
Date date1 = new Date();

int taskSize = 5;
ExecutorService pool = Executors.newFixedThreadPool(taskSize);   // 创建一个线程池
List<Future> list = new ArrayList<Future>();   // 创建多个有返回值的任务
for (int i = 0; i < taskSize; i++) {
Callable c = new MyCallable(i + " ");
Future f = pool.submit(c);   // 执行任务并获取Future对象
list.add(f);
}
pool.shutdown();  // 关闭线程池

// 获取所有并发任务的运行结果
for (Future f : list) {
// 从Future对象上获取任务的返回值,并输出到控制台
System.out.println(">>>" + f.get().toString());
}

Date date2 = new Date();
System.out.println("-程序结束运行-,运行时间["+(date2.getTime() - date1.getTime()) + "毫秒]");
}
}

class MyCallable implements Callable<Object> {
private String taskNum;

MyCallable(String taskNum) {
this.taskNum = taskNum;
}

public Object call() throws Exception {
System.out.println(">>>" + taskNum + "任务启动");
Date dateTmp1 = new Date();
Thread.sleep(1000);
Date dateTmp2 = new Date();
long time = dateTmp2.getTime() - dateTmp1.getTime();
System.out.println(">>>" + taskNum + "任务终止");
return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
}
}

ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,调用返回Future对象的get()方法,会阻塞直到计算完成。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: