第一种方式:通过编写类继承Thread,重写run方法实现
实现实例:
public class ThreadTest {
public static void main(String[] args) {
System.out.println("main方法开始");
Thread01 thread01 = new Thread01();
thread01.start();
System.out.println("main方法结束");
}
/**
* 创建线程的第一种方式
*/
public static class Thread01 extends Thread{
@Override
public void run() {
System.out.println("第一种创建线程的方式:通过继承Thread的方式,再通过start方式开启线程!!");
}
}
}
执行结果:
第二种方式:通过实现Runnable接口实现
实现实例:
public class ThreadTest {
public static void main(String[] args) {
System.out.println("main方法开始");
new Thread(new Runnable01()).start();
System.out.println("main方法结束");
}
/**
* 创建线程的第二种方式
*/
public static class Runnable01 implements Runnable{
@Override
public void run() {
System.out.println("创建线程的第二种方式:通过实现Runnable接口");
}
}
}
执行结果:
第三种创建线程的方式:通过实现Callable接口,连同FutureTask一同使用
实例代码:
public class ThreadTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main方法开始");
FutureTask<String> futureTask = new FutureTask<>(new Callable01());
new Thread(futureTask).start();
System.out.println("main方法结束,线程执行的结果为:->"+futureTask.get());
}
/**
* 第三种创建线程的方式
*/
public static class Callable01 implements Callable<String>{
@Override
public String call() throws Exception {
String msg="第三种创建线程的方式:通过实现Callable接口实现,这种方式的特点是可以连同FutureTask一同使用,可获取业务执行之后的结果!";
return msg;
}
}
}
结果:
第四种创建线程的方式:通过创建线程池实现创建
实例:
public class ThreadTest {
static ExecutorService service = Executors.newFixedThreadPool(2);//实例创建的为使用的固定线程的线程池
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main方法开始");
service.execute(new Runnable01());//传入一个Runable对象
service.shutdown();//关闭线程池
System.out.println("main方法结束");
}
}
区别:
第一种方式和第二种方式不能得到返回值,第三种方式可以获取返回值(Runnable也可以联合Future获取返回值)
第一二三种方式都不能控制资源
第四种方式可以可以控制资源,性能稳定