Java 线程
线程实现/创建的方式
Java 中线程的实现/创建通过继承 Thread 类和实现 Runnable 和 Callable 接口三种方式。
- 可以用 Thread 和 ExecutorService 运行
- Thread 本质上是一个实现了 Runnable 接口的类,代表一个线程实例。
- 启动线程的唯一方式是调用
start()
方法。 start()
是一个 Native 方法。start()
将启动一个新的线程并执行run()
方法。- 这种情况下启动的线程不能有返回值。
public class MyThread extends Thread{
@Override
public void run(){
System.out.println("MyThread.run()");
}
}
MyThread mythread = new MyThread();
mythread.start();
- 可以用 Thread 和 ExecutorService 运行
- Runnable 接口的实现类也不能有返回值。
- 当类已经继承了其他类(非 Thread 类),而且任务无返回值,那么就必须实现 Runnable 接口
public MyThread extends OtherClass implements Runnable{
@Override
public void run(){
System.out.println("MyThread.run()");
}
}
MyThread mythread = new MyThread();
Thread thread = new Thread(mythread);
thread.run();
// 当传入一个 Thread target 参数给Thread后,Thread就会调用
// target.run() 方法
public void run(){
if(target != null){
target.run();
}
}
- 只能用 ExecutorService 运行
- 有返回值的任务必须实现 Callable 接口
- 执行 Callable 任务后可以获取一个 Future对象
- 在 Future 对象行调用
get()
方法可以得到返回的Object
- 抛出异常
public interface Callable<V> {
V call() throws Exception;
}
public class MyCallable implements Callable<Integer> {
int number;
// standard constructors
public Integer call() throws InvalidParamaterException {
int fact = 1;
// ...
for(int count = number; count > 1; count--) {
fact = fact * count;
}
return fact;
}
}
// 创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(taskSize);
// 创建有多个返回值的任务
List<Future> list = new ArrayList<Future>();
for(int i=0; i< taskSize; i++){
Callable c = new MyCallable(i+" ");
// 执行任务并获取 Future 对象
Future f = pool.submit(c);
list.add(f);
}
// 关闭线程池
pool.shutdown();
// 获取所有并发任务的结果
for(Future f: list){
System.out.println("res: " + f.get().toString());
}