1.继承Thread类。通过重写其run方法,new出其对象,start方法实现,不足之处在于产用了继承的名额,java类是单继承的。
public class Threadtest extends Thread {
public static void main(String[] args) {
Threadtest thread = new Threadtest();
thread.start();
}
@Override
public void run(){
System.out.println("hallo world");
}
}
2.实现Runnable接口。实现run方法,使用依然使用Thread类进行创建,这种是更为常见的做法。
public class Runnabletest implements Runnable{
public static void main(String[] args) {
Thread thread = new Thread(new Runnabletest());
thread.start();
}
@Override
public void run() {
System.out.println("hello world");
}
}
或使用匿名内部类进行实现,
public class noNameTest {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println("hello world");
}});
thread.start();
}
}
同时因为runnbable接口是函数式接口,故可以使用lambda表达式表示它。
public class LambtaTest {
public static void main(String[] args) {
Thread thread = new Thread(()->System.out.println("hello world"));
thread.start();
}
}
3.实现Callable接口。实现call方法,需要额外创建FutureTask<返回值类型>类,后通过Thread类进行创建,我们可以通过futureTask类中的get方法获取线程返回值。不同与runnable接口的实现,我们可以得到线程执行完后的结果。
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class CallableTest implements Callable {
public static void main(String[] args) {
try {
FutureTask<String> futureTask = new FutureTask<>(new CallableTest());
Thread thread = new Thread(futureTask);
thread.start();
String data = futureTask.get();
System.out.println(data);
}catch (Exception e){
System.out.println("ERROR"+e);
}
}
@Override
public String call() throws Exception {
return "hello world";
}
}
4.利用线程池创建线程。实现Callable接口或者Runnable接口都可以,由ExecutorService来创建线程。
e.g Runnable简易实现
import java.util.concurrent.*;
public class ThreadPool implements Runnable {
public static void main(String[] args) throws ExecutionException,InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(10);
for(int i = 0; i<10;i++) {
service.execute(new ThreadPool());
}
}
@Override
public void run() {
System.out.println("hello world");
}
}
Callable简易实现
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
@Slf4j
public class ThreadPOOLCallable implements Callable {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future future = executorService.submit(new ThreadPOOLCallable());
try {
log.info("开始时间:{}",System.currentTimeMillis());
log.info("线程输出"+future.get());
log.info("结束时间:{}",System.currentTimeMillis());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public String call() throws Exception {
return "hello world";
}
}
总结:以上几种方式其底层都是基于Runnable。