补充-jdk5新增多线程实现方式

创建多线程的原始两种方式

  1、继承Thread类

  2、实现Runable接口

jdk5新增的两种方式

1、实现Callable接口

  jdk5:新增创建线程方式:实现Callable
   *        与使用Runnable相比,Callable功能更强大
   *            1、相比run() 方法,可以有返回值
   *            2、方法可以抛出异常
   *            3、支持泛型的返回值
   *            4、需要借助FutureTask类,比如获取返回结果

   *    Futrue接口
   *        1、可以对具体Runnable、Callable任务的执行结果进行取消、查询、是否完成、获取结果等
   *        2、FutureTask同时实现了Runnable、Future接口。它既可以作为Runnable被线程执行,
   *            又可以作为Future得到Callable的返回值


  如何理解实现Callable接口比实现Runnable接口创建多线程的功能强大
   *    1、创建call方法可以有返回值
   *    2、可以抛出异常,被外面操作捕获,获取异常信息
   *    3、Callable支持泛型 (安全)

package callable_test;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 *     创建线程的方式三:
 * jdk5:新增创建线程方式:实现Callable
 *        与使用Runnable相比,Callable功能更强大
 *            1、相比run() 方法,可以有返回值
 *            2、方法可以抛出异常
 *            3、支持泛型的返回值
 *            4、需要借助FutureTask类,比如获取返回结果
 *
 *    Futrue接口
 *        1、可以对具体Runnable、Callable任务的执行结果进行取消、查询、是否完成、获取结果等
 *        2、FutureTask同时实现了Runnable、Future接口。它既可以作为Runnable被线程执行,
 *            又可以作为Future得到Callable的返回值
 *
 *    如何理解实现Callable接口比实现Runnable接口创建多线程的功能强大
 *    1、创建call方法可以有返回值
 *    2、可以抛出异常,被外面操作捕获,获取异常信息
 *    3、Callable支持泛型 (安全)
 * @author Gary
 * @time 2019年8月22日
 */

//1、创建一个实现Callable接口的实现类
class NumThread2 implements Callable {
    int sum = 0;
    
    //2、实现call方法 类同run()
    public Object call() throws Exception {
        for(int i=0; i<100; i++) {
            if(i%2==0) {
                System.out.println(Thread.currentThread().getName()+"="+i);
                sum += i;
            }
        }
        return sum;
    }
    
}

public class TestCallable {

    public static void main(String[] args) {
        //3、创建Callable接口实现类的对象
        NumThread2 numT2 = new NumThread2();
        //4、将次Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
        FutureTask<NumThread2> ft = new FutureTask<NumThread2>(numT2);
        
        Thread thread = new Thread(ft);
        thread.start();
        
        try {
            //6、获取Callable中call方法的返回值
            //get方法的返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值
            
            Object sum = ft.get();
            System.out.println("ft.get() = "+sum
                    );
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}

 

2、使用线程池

 *     ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor
 *         void execute(Runnable command): 执行任务、命令,没有返回值,一般用来执行Runnable
 *         <T>Future<T>submit(Callable<T>task): 执行任务,有返回值,一般用来执行Callable
 *         void shutdown(): 关闭连接池
 *
 *     使用线程池创建线程
 *  Executors: 工具类,线程池的工厂类,用于创建并返回不同类型的线程池
 *         Executors.newCachedThreadPool(): 创建一个可根据需要创建新线程的线程池
 *      Executors.newFixedThreadPool(): 创建一个可重用固定线程数的线程池
 *      Executors.newSingleThreadExecutor(): 创建一个只有一个线程额线程池
 *      Executors.newScheduledThreadPool(n): 创建一个线程池,他可安排在给定延迟后运行命令或者定期的执行
 *  
 *      创建多线程有4中方式:
 *      1、继承Thread类
 *      2、实现Runnable接口
 *      3、实现Callable接口
 *      4、使用多线程

package pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 *     ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor
 *         void execute(Runnable command): 执行任务、命令,没有返回值,一般用来执行Runnable
 *         <T>Future<T>submit(Callable<T>task): 执行任务,有返回值,一般用来执行Callable
 *         void shutdown(): 关闭连接池
 * 
 *     使用线程池创建线程
 *  Executors: 工具类,线程池的工厂类,用于创建并返回不同类型的线程池
 *         Executors.newCachedThreadPool(): 创建一个可根据需要创建新线程的线程池
 *      Executors.newFixedThreadPool(): 创建一个可重用固定线程数的线程池
 *      Executors.newSingleThreadExecutor(): 创建一个只有一个线程额线程池
 *      Executors.newScheduledThreadPool(n): 创建一个线程池,他可安排在给定延迟后运行命令或者定期的执行
 *  
 *      创建多线程有4中方式:
 *      1、继承Thread类
 *      2、实现Runnable接口
 *      3、实现Callable接口
 *      4、使用多线程
 * @author Gary
 * @time 2019年8月22日
 */
public class Test1 {

    public static void main(String[] args) {
        
        //1、提供指定线程数量的线程池
        ExecutorService service = Executors.newFixedThreadPool(3);
        ThreadPoolExecutor service1 = (ThreadPoolExecutor)service;
        //    设置线程池的属性
        service1.setCorePoolSize(2);
        System.out.println(service.getClass());
        //2、执行指定的线程的操作,需要提供实现的Runnable接口或Callable接口实现类对象
        service.execute(new NumberThread());  //适用于Runnable
        service.execute(new NumberThread());
        //3、关闭连接池
        service.shutdown();
//        service.submit(); // 适用于Callable
    }
}

class NumberThread implements Runnable {
    
    public void run() {
        for(int i=0; i<100; i++) {
            System.out.println(Thread.currentThread().getName()+"=="+i);
        }
    }
}

 

上一篇:Salted hash password


下一篇:[Offer收割]编程练习赛5-1 小Ho的防护盾