并发编程学习总结(一) :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;}}







0 0
原创粉丝点击