学习线程池和lambda表达式的理解java
在多线程中,咱们只须要一个任务类,为了防止建立多个任务类,这个时候就须要用到单例模式,单例模式有两种设计:编程
下面用代码作个实例:设计模式
package com.wzlove.single; /** * 延迟加载(懒汉式) * 1.私有构造方法 * 2.建立本类对象,但不初始化 * 3.建立静态方法进行初始化对象并返回 * * 优势: * 使用到类的对象才会加载,不消耗内存 * 缺点: * 可能会出现线程安全问题,可是可使用同步代码块消除这个安全问题 * @author WZLOVE * @create 2018-07-19 10:36 */ public class DeplayedSingle { // 私有构造方法 private DeplayedSingle(){} // 建立本类对象,不初始化 private static DeplayedSingle instance ; // 静态方法初始化 public static DeplayedSingle getInstance(){ synchronized (DeplayedSingle.class){ if(instance == null){ instance = new DeplayedSingle(); } } return instance; } } package com.wzlove.single; /** * 当即加载(饿汉式) * 1.私有构造方法 * 2.建立本类的对象并初始化(私有的) * 3.建立静态方法获取本类对象 * * 优势: * 保证的线程的安全,没有线程安全问题 * 缺点: * 使用类就会加载,比较消耗内存 * @author WZLOVE * @create 2018-07-19 10:37 */ public class ImmediateSingle { private ImmediateSingle(){} private static ImmediateSingle instance = new ImmediateSingle(); public static ImmediateSingle getInstance(){ return instance; } }
线程池其实就是一个容纳多个线程的容器,其中的线程能够反复使用,省去了频繁建立线程对象的操做,
无需反复建立线程而消耗过多资源。做用是节省资源,原理是容器.数组
使用线程池的好处是减小在建立和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题.若是不使用线程池,
有可能形成系统建立大量同类线程而致使消耗完内存或者"过分切换"的问题.安全
建立线程池:多线程
步骤:ide
建立线程的第三种方式(这种方式不多见)函数式编程
package com.wzlove.executor; import java.util.ArrayList; import java.util.concurrent.Callable; /** * 线程的第三种建立方法 * Callable有返回值而且能够抛出异常 * @author WZLOVE * @create 2018-07-18 14:14 */ public class CallableImpl implements Callable<String> { private static ArrayList<String> arrayList = new ArrayList<>(); static{ arrayList.add("1"); } @Override public String call() throws Exception { return Thread.currentThread().getName(); } } package com.wzlove.executor; import java.util.concurrent.*; /** * 测试线程的第三中建立方式 * * @author WZLOVE * @create 2018-07-18 14:14 */ public class Demo { public static void main(String[] args) { // 建立实现Callable的实现类对象 Callable<String> callable = new CallableImpl(); // 建立FutureTask,并传递Callable接口的实现类对象 FutureTask task = new FutureTask(callable); // 建立线程池对象 // ExecutorService executor = Executors.newSingleThreadExecutor(); ExecutorService executor = Executors.newFixedThreadPool(3); executor.submit(callable); // 执行线程 executor.execute(task); try { System.out.println(task.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
lambda体现的是一种函数式编程的思想, 它强调的是作什么,而不是以什么形式作。函数
有且仅有一个抽象方法的接口,称为“函数式接口”。学习
Lambda省去面向对象的条条框框,格式由3个部分组成:
Lambda表达式的标准格式为:
(参数类型 参数名称) ‐> { 代码语句 }
格式说明:
实现Runnable接口的匿名内部类的实现:
public class Demo01Runnable { public static void main(String[] args) { // 匿名内部类 Runnable task = new Runnable() { @Override public void run() { // 覆盖重写抽象方法 System.out.println("多线程任务执行!"); } }; new Thread(task).start(); // 启动线程 } }
代码分析
- Thread 类须要Runnable 接口做为参数,其中的抽象run 方法是用来指定线程任务内容的核心;
- 为了指定run 的方法体,不得不须要Runnable 接口的实现类;
- 为了省去定义一个RunnableImpl 实现类的麻烦,不得不使用匿名内部类;
- 必须覆盖重写抽象run 方法,因此方法名称、方法参数、方法返回值不得再也不写一遍,且不能写错;
- 而实际上,彷佛只有方法体才是关键所在。
使用Lambda进行简化:
public class Demo01Runnable { public static void main(String[] args) { new Thread(()->System.out.println("多线程任务执行!")).start(); // 启动线程 } }
使用比较器举个例子:
// 建立数组 Integer[] arr = {1,8,3,4,9,2,5}; // 匿名内部类实现数组升序排序 Arrays.sort(arr,new Comparator<Integer>(){ @Override public int compare(Integer o1, Integer o2) { return 0; } }); // 使用lambda进行数组的升序排序 Arrays.sort(arr,( a, b)->{ return a - b ;});
在Lambda标准格式的基础上,使用省略写法的规则为:
虽然有省略写法,可是我感受这个有点灵活,因此不建议省略,由于代码是给别人看的,省略的话感受别人看起来会有点费劲.