实现线程有四种方式
分别是:
- 方式一:继承Thread类,重写run方法
- 方式二:实现Runnable接口,实现run方法
- 方式三:实现Callnable接口,实现call方法
- 方式四:利用ExecutorService线程池的方式创建线程
下面就来一一介绍:
方式一:继承Thread类,重写run方法
实现方式如下:
package com.lxk.thread1;
public class TestThread extends Thread{
@Override
public void run() {
System.out.println("测试线程!");
}
public static void main(String[] args) {
TestThread t1=new TestThread();
TestThread t2=new TestThread();
t1.start();
t2.start();
}
}
方式二:实现Runnable接口,实现run方法
实现Runnable接口,实现之后还需要用Thread类进行封装
具体实现方式如下:
package com.lxk.thread2;
public class TestThread implements Runnable{
@Override
public void run() {
System.out.println("测试线程!");
}
public static void main(String[] args) {
TestThread r=new TestThread();
Thread t1=new Thread(r);
Thread t2=new Thread(r);
t1.start();
t2.start();
}
}
方式三:实现Callnable接口,实现call方法
Callnable接口中有声明了一个方法call方法,该方法的返回类型不是void,而是Callnable接口的类泛型T
因此它是有返回值的,可以获取到线程执行体的返回值
线程类需要实现Callnable接口,在使用的时候需要先用FutureTask类封装线程类,然后用Thread类继续封装FutureTask类,然后调用start方法.
具体实现如下:
package com.lxk.thread3;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class MyThread implements Callable<Integer>{
int i=0;
@Override
public Integer call() throws Exception {
i++;
return i;
}
public static void main(String[] args) throws Exception {
Callable mt=new MyThread();
FutureTask<Integer> ft=new FutureTask<Integer>(mt);
Thread t=new Thread(ft);
t.start();
Integer integer = ft.get();//获取到线程执行体的返回值
System.out.println(integer);
}
}
方式四:利用ExecutorService线程池的方式创建线程
该方法是jdk1.5之后才出现的,利用ExecutorService一次性创建很多个线程,在需要该线程的时候直接从该线程池中拿取就可以了.(池的概念可以类比jdbc连接池)
具体实现如下:
package com.lxk.thread4;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyThread implements Runnable{
public static void main(String[] args) throws Exception {
ExecutorService e=Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
Thread t=new Thread(new MyThread());
//执行线程体,那个都可以
// t.start();
// e.execute(t);
}
e.shutdown();
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("执行线程!");
}
}
总结:
方式一和方式二都是没有返回值的,实际使用的时候推荐使用方式二,因为java是面向接口编程的,java是单继承多实现,面向接口编程可以更好的对类进行扩展,因此推荐使用方式二
方式三是由返回值的,如果需要获取到线程执行体的返回值推荐使用方式三
方式四是线程池的思想,池里面既可以放方式一和方式二创建的线程也可以放方式三创建的线程.