zoukankan      html  css  js  c++  java
  • Java多线程之创建线程的三种方式比较

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6560057.html 

        一:继承Thread类创建线程

            1:继承Thread类定义线程子类;

            2:重写run()方法,定义线程的操作;

            3:通过创建的线程子类对象.start() 启动线程。

    package com.thread;   
    public class FirstThreadTest extends Thread{   
        public void run()  
        {    
            System.out.println(Thread.currentThread().getName());  
        }  
        public static void main(String[] args)  
        {  
                    new FirstThreadTest().start();    
        }  
      
    } 

        二:实现Runnable接口创建线程

            1:实现Runnable接口定义线程类;

            2:重写run()方法;

            3:创建Thread对象:把上面 实现runnable接口的线程类 的对象作为构造参数,创建出线程对象;

            4:由thread对象的start()方法启动线程;

    public class RunnableThreadTest implements Runnable  
    {  
        public void run()  
        {     
                System.out.println(Thread.currentThread().getName())
        }  
        public static void main(String[] args)  
        {  
                    new Thread(new RunnableThreadTest()).start();  
        }  
      
    } 

        三:通过Callable接口和Future创建线程

           1:创建Callable接口的实现类,并指明返回值类型;

           2:在实现类中重写call()方法,并返回结果;

           3:创建Future<V>类型的list接收线程的预期结果: List<Future<String>> results = new ArrayList<Future<String>>();

           4:通过线程池启动线程,并且把线程返回结果add到list中;

           5:遍历list时,通过每个元素的 get() 方法获取每个线程的实际运行结果值

    //实现callable接口,定义线程类
    class TaskWithResult implements Callable<String>{  
        private int id;  
        public TaskWithResult(int id){  
            this.id = id;  
        }  
       //重写call()方法,切记抛出异常,并返回值
        public String call() throws Exception {  
            return "result of task:" + id;  
        }  
    public class TestCallable {      
        public static void main(String[] args) {  
            //创建线程池
            ExecutorService es = Executors.newCachedThreadPool();
           //创建预期结果集合  
            List<Future<String>> results = new ArrayList<Future<String>>();  
    
            for(int i=0;i<5;i++){  
                //通过线程池启动线程,把线程结果保存到预期结果集合
                results.add(es.submit(new TaskWithResult(i)));  
            }  
            //遍历结果集合
            for(Future<String> fs : results){  
                try {  
                    //通过 结果.get() 方法获取每个线程运行结束后的返回值。并处理异常
                    System.out.println(fs.get());  
                } catch (InterruptedException | ExecutionException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  

    另一种启动callable实现类线程的办法:

    Callable<Result> ca = new Callable<Result>() {
                 public Result call() throws Exception {
                     System.out.println("当前线程名称是:" + Thread.currentThread().getName());
                     Thread.sleep(2000L);
                    return new Result("callable 执行完毕");
                 }
             };
             //包装对象
             FutureTask<Result> ft = new FutureTask<Result>(ca);
             try {            
              //启动线程执行
                new Thread(ft).start();
                //获取结果
                 System.out.println(ft.get().getMsg());
              } catch (Exception e) {
                 e.printStackTrace();
             }
         }

        四:对比

            1:继承Thread类创建线程:其run()方法没有返回值;通过start方法启动;由于Java不能允许多继承,一个类如果需要继承其他类就不能再定义为线程类了;run方法中的异常必须捕获并处理;

            2:实现runnable接口创建线程:其run()方法没有返回值;通过作为thread类的构造函数的参数被包装成thread类对象,再通过start方法启动(由此,可以同一个任务对象交给多个thread对象来运行,实现资源的共享以及并行处理);由于接口可以多实现,一个类可以继承其他类的同时实现runnable接口成为线程类;run方法中的异常必须捕获并处理;

            3:实现Callable接口创建线程:其call()方法有返回值;一般通过线程池来启动线程,也可以先包装成为FutureTask对象,然后再由futuretask对象包装成Thread对象通过start方法启动;call()方法可以抛出异常,直到在结果处通过get()方法获取结果时再处理异常;在主线程启动实现callable创建的线程时可以获得一个Future对象作为异步处理的预期结果,在通过future.get()方法时检测启动的线程是否已完成并返回结果,是则得到结果,否则阻塞主线程等待任务线程完成并返回结果;

                 

  • 相关阅读:
    2020.10.23 19级training 补题报告
    2020.10.17 天梯赛练习 补题报告
    2020.10.16 19级training 补题报告
    2020.10.9 19级training 补题报告
    2020.10.10 天梯赛练习 补题报告
    2020.10.3 天梯赛练习 补题报告
    2020.10.2 19级training 补题报告
    第十届山东省ACM省赛复现补题报告
    VVDI Key Tool Plus Adds VW Passat 2015 Key via OBD
    Xhorse VVDI Prog Software V5.0.3 Adds Many MCUs
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6560057.html
Copyright © 2011-2022 走看看