总结一下学习过程中创建线程的几种方法
一、直接实现Runnable接口
public class LiftOff implements Runnable
{
@Override
public void run()
{
System.out.println("线程");
}
}
然后再实例化一个Thread传入LiftOff实例,调用start方法
LiftOff liftOff = new LiftOff();
Thread thread = new Thread(liftOff);
thread.start();
二、继承Thread类,重写run方法
public class MyThread extends Thread
{
@Override
public void run()
{
System.out.println("MyThread");
}
}
MyThread myThrea = new MyThread();
myThrea.start();
三、当希望任务完成时能够有返回值,可以实现Callable接口,而不是Runnable,Callable是具有类型参数的泛型,它的类型参数是指定方法call返回值的类型
class TaskWithResult<T> implements Callable<T>
{
private T result;
public TaskWithResult(T result)
{
this.result = result;
}
@Override
public T call() throws Exception
{
return result;
}
}
使用Thead执行线程
TaskWithResult<String> taskWithResult = new TaskWithResult<>("call");
FutureTask futureTask = new FutureTask(taskWithResult);
Thread thread = new Thread(futureTask);
thread.start();//执行线程
TimeUnit.SECONDS.sleep(2);//设置main线程休眠2秒,以便打印结果
//判断任务是否完成
if (futureTask.isDone())
System.out.println(futureTask.get());//输出返回值
使用执行器Executors创建线程池。
//使用执行器来完成线程
ExecutorService exec = Executors.newCachedThreadPool();
Future future = null;
try
{
future = exec.submit(taskWithResult);
} finally
{
//关闭执行器,正在执行的任务不受影响
exec.shutdown();
}
TimeUnit.SECONDS.sleep(2);
if (future.isDone())
System.out.println(future.get());
注:
Executors类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。
- public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。 - public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60秒钟未被使用的线程。 - public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。 - public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。 - ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。