public class MyThread extends Thread { @Override public void run() { // 执行业务逻辑 } public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.start(); } }
public class MyRunnable implements Runnable { @Override public void run() { // 执行业务逻辑 } public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } }
FutureTask 的出现是为了弥补 Thread 的不足而设计的,可以让程序员跟踪、获取任务的执行情况、计算结果
public class MyCallable implements Callable<Integer>{ @Override public Integer call() throws Exception { System.out.println("子线程开始计算"); Thread.sleep(2000); System.out.println("子线程结束计算"); return 100 * 100; } public static void main(String[] args) throws ExecutionException, InterruptedException { // 实例化Callable对象 MyCallable myCallable = new MyCallable(); // 使用FutureTask包装 FutureTask<Integer> futureTask = new FutureTask<>(myCallable); // 创建一个线程执行任务 Thread thread = new Thread(futureTask); thread.start(); Thread.sleep(1000); System.out.println("主线程执行"); // 使用get()方法会阻塞主线程,直到子线程执行完成返回结果 int result = futureTask.get(); System.out.println("子线程计算结果: " + result); } }
子线程开始计算 主线程执行 子线程结束计算 子线程计算结果: 10000
为什么要使用线程池呢?
当不是执行一次性任务的时候,如果不使用线程池,那么就要频繁的创建和销毁线程,这是一个比较消耗资源的操作,使用线程池可以灵活的调整线程资源的占用,防止消耗过多的内存
在Java中已经提供了ExecutorSerice、Executors等工具类为我们快速的创建线程池
常用的常见线程的方法有