1.继承Thread类
通过继承Thread类并重写run方法实现创建线程
public class ThreadDemo {
public static void main(String[] args) {
MyThread2 myThread2 = new MyThread2();
myThread2.start();
}
}
class MyThread2 extends Thread {
@Override
public void run() {
System.out.println("say Hello!");
}
}
2.实现Runnable接口
public class RunnableDemo {
public static void main(String[] args) {
Thread thread = new Thread(new MyThread3());
thread.start();
}
}
class MyThread3 implements Runnable {
@Override
public void run() {
System.out.println("Runnable !!");
}
}
3.实现Callable接口
通过实现Callable接口的方法创建线程,可获取线程的返回值。
该方法可以创建异步有返回值的多线程。Thread类支持Runnable的构造不支持Callable的构造,因此无法直接new Thread()创建,需要配合使用FutureTask(Future的实现类),它拥有Callable的构造方法,FutureTask又实现了Runnable接口,根据Java多态的特性将其放入Thread的构造中就间接使用了Callable。
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> futureTask = new FutureTask<>(new MyThread4());
Thread thread = new Thread(futureTask);
thread.start();
//get()是阻塞的
System.out.println(futureTask.get());
}
}
class MyThread4 implements Callable<String> {
@Override
public String call() throws Exception {
return "Callable !!";
}
}
4.使用线程池创建线程
这种情况用的比较多,初始化线程池后,用的时候直接拿,用完再放回去,很方便。
public class FutureTaskDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//获取单例的线程池
ThreadPoolExecutor threadPool = MyThreadPool.getInstance();
//线程池创建线程
FutureTask<String> futureTask = new FutureTask<>(new MyThread());
threadPool.execute(futureTask);
System.out.println(futureTask.get());
}
}
class MyThread implements Callable<String> {
@Override
public String call() throws Exception {
return "say hello.";
}
}
//线程池的初始化(单例模式)
class MyThreadPool {
private MyThreadPool() {}
public static final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
5,
10,
10000,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(5),
Thread::new,
new ThreadPoolExecutor.CallerRunsPolicy()
);
public static ThreadPoolExecutor getInstance() {
return threadPool;
}
}