1.总结
线程的创建总结起来总共有两种方法,一个是继承Thread类,另一个是实现Runnable接口
package demo06; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class ThreadCreateStudy { public static void main(String[] args) throws InterruptedException, ExecutionException { Thread t1 = new MyThread(); t1.start(); Thread t2 = new Thread(new MyRunnable()); t2.start(); FutureTask<String> future = new FutureTask<String>(new MyCallable()); Thread t3 = new Thread(future); t3.start(); System.out.println(future.get());; } } class MyThread extends Thread{ @Override public void run() { System.out.println("My Thread"); } } class MyRunnable implements Runnable{ @Override public void run() { System.out.println("MyRunnable"); } } class MyCallable implements Callable<String>{ @Override public String call() throws Exception { return "MyCallable"; } }
如代码所示,前两种没什么好说的,就是通用的创建线程的方式,但是缺点是没有返回值,只是一个处理计算的过程.
如果线程需要有返回值的话就需要实现Callable接口,并且包装成FutureTask类
public class FutureTask<V> implements RunnableFuture<V> { //.... }
FutureTask实现了Runnable接口,所以直接用线程运行,并且通过get()方法可以获取数据.
如果线程没有运行完,则会阻塞,FutureTask会响应中断.
2.通过线程池来管理线程
如果用户无限制的创建线程会导致内存不足,所以线程需要通过Executors框架来进行管理,总共有以下几种方式:
2.1.newFixedThreadPool 根据输入的int参数来创建固定线程
2.2.newCachedThreadPool 根据任务数量来创建线程的个数.
2.3.newSingleThreadPool 只有一个线程,某些场景不需要并发的情况下可以使用这个来简化线程安全问题.
2.4.newScheduleThreadPool 按固定时间执行,感觉某些定时任务就是通过这个实现的. 比Timer好的情况是封闭了多线程的复杂性.
3.建议多使用线程池,阿里建议使用ThreadPoolFactory通过建立参数的形式来建立,既然jdk封装了Executors框架,那么也是可以使用的,两种情况需要结合具体项目实践.