并发编程学习总结(一) :java 创建线程的三种方式的优缺点和实例
来源:互联网 发布:2016年4月进出口数据 编辑:程序博客网 时间:2024/05/22 07:41
java 创建线程有三种方式:
(一) 实现Runnable接口
优点:(1) 创建线程的同时可以继承其他的类,从而可以扩展类的功能。
(2) 同一个实现Runnable接口的实例可以作为多个Thread的target,这样可以实现资源的共享。
缺点:相对于继承Thread类,实现Runnable接口代码要繁琐一些
代码实例如下:
public class ImplementsRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());}public static void main(String[] args) {// TODO Auto-generated method stub// 输出主线程的相关信息System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());// 创建thread1线程ImplementsRunnable runnableTarget = new ImplementsRunnable();Thread thread1 = new Thread(runnableTarget,"ThreadName1");thread1.start();// 以匿名内部类的形式创建target 创建thread2线程new Thread(new Runnable() {public void run() {System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());}},"ThreadName2").start();}}
输出结果:main ThreadId: 1 ThreadName1 ThreadId: 9 ThreadName2 ThreadId: 10
(二) 继承Thread 类,重载Thread类的run()方法。事实上Thread类也是实现了Runnable接口。
优点:代码相对其他两种方式更简洁
缺点:由于java的继承机制是单一继承,继承Thread类就不能继承其他的类。
代码实例:
public class ExtendsThread extends Thread{public ExtendsThread(String threadName) {super(threadName);}public void run() {System.out.println("ThreadName: " + getName());}public static void main(String[] args) {// TODO Auto-generated method stub// 输出主线程的相关信息System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());// 创建子线程ExtendsThread et = new ExtendsThread("childThread");et.start();}}
(三) 实现Callable<V>接口 并实现接口的唯一方法call()
有些场景会希望得到线程的计算结果,这时可以实现Callable<V> 接口。Callable<V>接口和Runnable接口都是封装了一个异步任务,不同的是
Callable<V>接口具有返回值。同时Call<V>接口还是一个参数化的类型,这个参数就是线程的返回参数类型,比如线程若返回整型则Callable<Integer>
,若返回字符类型则为Callable<Object>。
通过实现Callable<V>接口创建线程,需要用到一个包装器FutureTask<V>,这个包装器同时实现了Runnable和Future<V>接口,它可以将Callable<V>
对象转换为Runnable和Future。
public interface Callable<V> { V call() throws Exception; }public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run();}public class FutureTask<V> implements RunnableFuture<V> {......}
代码实例:
public class ImplemetsCallable implements Callable<Integer>{// 实现call()方法public Integer call() {return 35;}public static void main(String [] args) throws InterruptedException, ExecutionException, TimeoutException {ImplemetsCallable ic = new ImplemetsCallable();// 创建包装器 FutureTask 同时实现了Runnable和Future接口 可以将Callable 转换成Future和RunnableFutureTask<Integer> task = new FutureTask<Integer>(ic);Thread t = new Thread(task);t.start();// 调用FutureTask的get() 方法 获取线程的计算结果// 如果线程没有计算完结果 则get()方法会阻塞 直到线程计算完结果返回System.out.println(task.get());// get(long timeout, TimeUnit unit)方法在指定时间内获取线程计算结果,超时则抛出 TimeoutException异常// 如果运行计算结果的线程被中断则get()和get(long timeout, TimeUnit unit)方法都将抛出InterruptedException异常System.out.println(task.get(10000, TimeUnit.MILLISECONDS));}}
以下代码是通过使用线程池的方式创建线程:
public class TestCallable {public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println("程序开始执行");List<Future> list = new ArrayList<Future>();int taskSize = 5; // 创建一个线程池 ExecutorService pool = Executors.newFixedThreadPool(taskSize); for (int i = 0; i<taskSize; i++) {MyCallable mc = new MyCallable("i "+i);Future f = pool.submit(mc);list.add(f);}for (Future f : list) {try {System.out.println(f.get().toString());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ExecutionException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class MyCallable implements Callable<Object> {private String name;public MyCallable(String name) {this.name = name;}public Object call() {System.out.println("任务开始执行>>>>");long beginTime = System.currentTimeMillis();try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}long endTime = System.currentTimeMillis();long durTime = endTime - beginTime;System.out.println("任务执行完毕>>>>");return name + "任务执行完毕>>>> 总耗时: "+ durTime;}}
- 并发编程学习总结(一) :java 创建线程的三种方式的优缺点和实例
- 并发编程学习总结(一) :java 创建线程的三种方式的优缺点和实例(转载自:http://blog.csdn.net/u011784767/article/details/51315007)
- 创建线程的三种方式优缺点
- Java学习之多线程--创建线程的三种方式
- Java线程总结(一):创建线程的两种方式Thread和Runnable
- 创建线程的三种方式总结
- 并发编程学习总结(三) : 线程的中断详解
- Java并发总结(一): 线程的介绍及创建
- 多线程/并发笔记:线程创建的三种方式
- java创建线程的三种方式
- java创建线程的三种方式
- Java创建线程的三种方式
- Java线程创建的三种方式
- Java创建线程的三种方式
- Java创建线程的三种方式
- Java线程的三种创建方式
- java创建线程的三种方式
- java创建线程的三种方式
- linux基础之常用命令(3)
- Android WebView
- 创建自己的Cocoapods库
- css3盒子布局-定义盒子的弹性空间(box-flex)
- /*C#:扩展方法*/ 《自学系列》
- 并发编程学习总结(一) :java 创建线程的三种方式的优缺点和实例
- (礼拜三log)前端开发:replace函数
- javaweb学习总结(六)——Servlet开发(二)
- log4jdbc数据库访问日志框架使用
- 机器学习\数据挖掘学习日记20160504
- css选择器
- STM32F103 USART DMA收发不定长数据
- iOS热更新,JSPatch初探
- javaweb学习总结(七)——HttpServletResponse对象(一)