线程的基本操作-新建线程的四种方法
1 Thread类,重写run()方法
继承Thread类,重写run()方法
public class Test extends Thread{ public static void main(String[] args) { new Test().start(); } @Override public void run(){ System.out.println("hello"); } }
通过匿名内部类,重写run()方法:
public class Test { public static void main(String[] args) { new Thread(){ @Override public void run(){ System.out.println("hello"); } }.start(); } }
2 实现Runnable接口
利用Thread类的构造方法,传入一个实现了Runnable接口的对象。
public class Test implements Runnable{ public static void main(String[] args) { new Thread(new Test()).start(); } public void run() { System.out.println("hello"); } }
3 实现callable接口
-
与使用Runnable相比, Callable功能更强大些
-
实现的call()方法相比run()方法,可以返回值
-
方法可以抛出异常
-
支持泛型的返回值
-
需要借助FutureTask类,比如获取返回结果
-
Future接口可以对具体Runnable、Callable任务的执行结果进行取消、查询是否完成、获取结果等。
-
FutureTask是Futrue接口的唯一的实现类
-
FutureTask 同时实现了Runnable, Future接口。它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
-
public class Test implements Callable { public static void main(String[] args) { FutureTask<Integer> futureTask = new FutureTask<>(new Test()); new Thread(futureTask).start(); try { Integer integer = futureTask.get(); System.out.println(integer); } catch (Exception e) { e.printStackTrace(); } }
4 使用线程池
public class Test { public static void main(String[] args) { ExecutorService es = new ThreadPoolExecutor( 5,//corePoolSize 30,//maxmumPoolSize 0L,//keepAliveTime TimeUnit.MICROSECONDS,//TimeUnit new LinkedBlockingDeque<Runnable>(),//workQueue Executors.defaultThreadFactory(),//threadFactory new ThreadPoolExecutor.AbortPolicy() //ExecutionHandler ); es.execute(new Runnable() { @Override public void run() { System.out.println("hello"); } }); } }
corePoolSize:指定了线程池中线程的数量
maxmumPoolSize:指定了线程池中最大线程的数量
keepAliveTime:当线程池数量超过corePoolSize时,多余空闲线程的存活时间
TimeUnit:keepAliveTime的单位
workQueue:任务队列,被提交但是未执行的任务
threadFactory:线程工厂,用于创建线程,一般默认
ExecutionHandler:拒绝策略,当等待队列满了后触发拒绝策略。JDK的ThreadPoolExecutor类中有四个静态内部类,定义了四个策略:
DiscardPolicy:只要线程池未关闭,该策略会直接在调用者线程里运行被丢弃的任务。
DiscardOldestPolicy:该策略会丢弃一个队列最前面的线程,然后尝试再次提交当前任务。
浙公网安备 33010602011771号